Dereferencing in the case of $ _ [0], $ _ [1] ..... so on

see below code:

$scalar = 10; subroutine(\$scalar); sub subroutine { my $subroutine_scalar = ${$_[0]}; #note you need the {} brackets, or this doesn't work! print "$subroutine_scalar\n"; } 

In the above code, you can see the comment written β€œnote that you need the brackets {}, or it won’t work!”, Please explain the reason why we cannot use the same statement:

 my $subroutine_scalar = $$_[0]; 

i.e. without curly braces.

+7
perl
source share
4 answers

Many people have already given the correct answers here. I wanted to add an example that I found illuminating. Read the perldoc perlref documentation for more details .

Your problem is ambiguous, you have two operations $$ and [0] working on the same identifier _ , and the result depends on which operation is performed first. We can make it less ambiguous by using the support braces ${ ... } . $$_[0] could (for a person anyway) possibly mean:

  • ${$$_}[0] - play the scalar $_ , then take its first element.
  • ${$_[0]} - take element 0 array @_ and @_ it.

As you can see, these two cases relate to completely different variables, @_ and $_ .

Of course, for Perl this is not ambiguous, we just get the first option, since dereferencing is done before the key search. We need supportive curly braces to override this dereferencing, and therefore your example does not β€œwork” without parentheses.

You may consider somewhat less confusing functionality for your routine. Instead of trying to do two things at once (get an argument and dereference it), you can do this in two steps:

 sub foo { my $n = shift; print $$n; } 

Here we take the first argument off @_ with shift , and then play it out. Clean and simple.

Most often, you will not use references to scalar variables. And in these cases, you can use the arrow operator ->

 my @array = (1,2,3); foo(\@array); sub foo { my $aref = shift; print $aref->[0]; } 

I believe that using the arrow operator is preferable to the $$ syntax.

+8
source share

${ $x }[0] captures the value of element 0 in the array referenced by $x .

${ $x[0] } captures the scalar value referenced by element 0 of the @x array.

 >perl -E"$x=['def']; @x=\'abc'; say ${ $x }[0];" def >perl -E"$x=['def']; @x=\'abc'; say ${ $x[0] };" abc 

$$x[0] not suitable for ${ $x }[0] .

 >perl -E"$x=['def']; @x=\'abc'; say $$x[0];" def 
+2
source share
 my $subroutine_scalar = $$_[0]; 

coincides with

 my $subroutine_scalar = $_->[0]; # $_ is array reference 

On the other hand,

 my $subroutine_scalar = ${$_[0]}; 

dereferences scalar ref for the first element of the @_ array and can be written as

 my ($sref) = @_; my $subroutine_scalar = ${$sref}; # or $$sref for short 
+2
source share

Because $$_[0] means ${$_}[0] .

Consider these two pieces of code that print 10 :

 sub subroutine1 { my $scalar = 10; my $ref_scalar = \$scalar; my @array = ($ref_scalar); my $subroutine_scalar = ${$array[0]}; print "$subroutine_scalar\n"; } sub subroutine2 { my @array = (10); my $ref_array = \@array; my $subroutine_scalar = $$ref_array[0]; print "$subroutine_scalar\n"; } 

In subroutine1 , @array is an array containing the $scalar . So, the first step is to get the first element of $array[0] , and then revere it.

While subroutine2 , @array is an array containing scalar 10 , and $ ref_array is its reference. So, the first step is to get the $ref_array , and then index the array.

+1
source share

All Articles