简体   繁体   中英

Usecase of an reference to scalar in perl?

I'm learning perl references, I understand the usefullness of the references to hases or arrays. But thinking about in what scenarios can be useful a reference to an scalar value.

my $x = 1;
my $sr = \$x;

where can be useful to use $$sr , instead of direct use of $x ?

For example, when traversing any deep hashref structure, isn't the common practice returning a reference if the given node is hashref or arrayref, but returning directly the scalar value instead of returning a reference to the scalar?

Exists some functions or modules what uses or return references to scalars, instead of returning the scalar's value?

In a subroutine, when you want to directly modify the values being passed into it.

eg

sub increment_this {
     my ( $inc_ref ) = @_;
     ${$inc_ref}++;
}  

Bit of a trivial case I know, but perhaps more pertinent would be examples like chomp which removes trailing letters from a variable or $_ .

If you think about it though - $_ is often effectively a reference. If you do this:

my @array = qw ( 1 2 3 );
foreach ( @array ) {
    $_++;
}

print @array; 

Modifying $_ has modified the contents of the array.

I think the real answer lies in your question itself: References to scalars are not terribly useful , and you can probably just ignore that they exist when writing code. The main usefulness as hinted at by perreal is that you can point to the same memory location: Share a variable between objects.

However, for curiosity and academic purposes, one rather obscure thing comes to mind, besides the good examples left by perreal and Sobrique. You can open a file handle to print to a variable:

use strict;
use warnings;
use Data::Dumper;

my $string;
open my $fh, ">", \$string or die $!;
print $fh "Inside the string";

print Dumper $string;
# prints $VAR1 = 'Inside the string';

When you want to share a scalar between objects:

my $v = 1;
my %h1 = (a=>\$v);
my %h2 = (b=>\$v);   
$v++;
print ${$h1{a}}, "\n";
print ${$h2{b}}, "\n";

prints:

2
2

It is usefull when you have to pass huge strings to a sub, and don't want to do a copy of them to make faster and don't waste the memory:

sub my_sub {
    my $str = shift;  #makes a copy of a reference => cheaper
    #do something with $$str
}

#...
$x = ' ... large string ...';
my_sub(\$x);

@TLP mentioned file handles, which prompted another example:

Passing around file handles. Good practice for manipulating files is to use lexical file handles, to avoid namespace pollution.

sub write_header {
  my ( $fh_ref ) = @_;
  print ${$fh_ref} "This is a header\n"; 
}

open ( my $output, ">", "output_filename" );
write_header ( \$output );
write_content ( \$output );
write_footer ( \$output );
close ( $output );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM