please see the 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 code above you can see the comment written "note you need the {} brackets, or this doesn't work!" . Please explain the reason that why we cant use the same statement as:
my $subroutine_scalar = $$_[0];
i.e. without using the curly brackets.
Many people have already given correct answers here. I wanted to add an example I found illuminating. You can read the documentation in perldoc perlref for more information.
Your problem is one of ambiguity, 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 curly braces ${ ... }
. $$_[0]
could (for a human anyway) possibly mean:
${$$_}[0]
-- dereference the scalar $_
, then take its first element. ${$_[0]}
-- take element 0
of the array @_
and dereference it. As you can see, these two cases refer to completely different variables, @_
and $_
.
Of course, for Perl it is not ambiguous, we simply get the first option, since dereferencing is performed before key lookup. We need the support curly braces to override this dereferencing, and that is why your example does not "work" without support braces.
You might consider a slightly less confusing functionality for your subroutine. Instead of trying to do two things at once (get the argument and dereference it), you can do it in two stages:
sub foo {
my $n = shift;
print $$n;
}
Here, we take the first argument off @_
with shift
, and then dereference it. Clean and simple.
Most often, you will not be using references to scalar variables, however. And in those cases, you can make use of the arrow operator ->
my @array = (1,2,3);
foo(\@array);
sub foo {
my $aref = shift;
print $aref->[0];
}
I find using the arrow operator to be preferable to the $$
syntax.
${ $x }[0]
grabs the value of element 0 in the array referenced by $x
.
${ $x[0] }
grabs the value of scalar referenced by the element 0 of the array @x
.
>perl -E"$x=['def']; @x=\'abc'; say ${ $x }[0];"
def
>perl -E"$x=['def']; @x=\'abc'; say ${ $x[0] };"
abc
$$x[0]
is short for ${ $x }[0]
.
>perl -E"$x=['def']; @x=\'abc'; say $$x[0];"
def
my $subroutine_scalar = $$_[0];
is same as
my $subroutine_scalar = $_->[0]; # $_ is array reference
On the other hand,
my $subroutine_scalar = ${$_[0]};
dereferences scalar ref for first element of @_
array, and can be written as
my ($sref) = @_;
my $subroutine_scalar = ${$sref}; # or $$sref for short
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With