Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I print this treating as a reference and treating it as a scalar?

In the following perl snippet:

my $a1 = [ qw(rock pop musical) ];  
my $b1 = [ qw( mystery action drama )];  
my $c1 = [ qw( biography novel periodical)];  

my @a2d = (  
    $a1,  
    $b1,  
    $c1  
);  

The @a2d is an array which contain references to arrays.
My question is why the following print the same thing (musical)?:

print ${$a2d[0]}[2],"\n";  
print $a2d[0][2],"\n";  

I expected the second to print ARRAY or give an error since the elements of the array are refences

like image 988
Cratylus Avatar asked Oct 12 '13 21:10

Cratylus


People also ask

What is a scalar reference?

A reference is a scalar variable that “points” or refers to another object which can be a scalar, an array, a hash, etc. A reference holds a memory address of the object that it points to. When a reference is dereferenced, you can manipulate data of the object that the reference refers to.

How to reference in Perl?

You can create references for scalar value, hash, array, function etc. In order to create a reference, define a new scalar variable and assign it the name of the variable(whose reference you want to create) by prefixing it with a backslash.


2 Answers

The $a2d[0] is an array reference. We can take this array reference and print out the 3rd entry:

my $ref = $a2d[0];
say ${ $ref }[2];
say $ref->[2];

These forms are equivalent. Now, we can do away with that intermediate variable, and get:

say ${ $a2d[0] }[2];
say $a2d[0]->[2];

If the dereference operator -> occurs between two subscripts, then it may be omitted as a shortcut:

say $a2d[0][2];

The arrow may be omitted when the left subscript is [...] or {...} and the right subscript it [...], {...} or (...).

This is also explained in perlreftut, which goes through these considerations in more depth. Reading that document should clear up many questions.

like image 59
amon Avatar answered Oct 04 '22 22:10

amon


The dereference is implied when you tack on indexes.

$a2d[0][2]

is short for

${ $a2d[0] }[2]

aka

$a2d[0]->[2]

Rather than giving a syntax error, Perl provides a useful shortcut for a common operation.

Other examples: $aoa[$i][$j], $aoh[$i]{$k}, $hoa{$k}[$i] and $hoh{$k1}{$k2}.

like image 27
ikegami Avatar answered Oct 04 '22 21:10

ikegami