cajwine
cajwine

Reputation: 3160

What exactly mean the ${...} in the perl?

Thinking about the next. Have a LIST

qw(a b c);

now, assign the LIST into nameless (anonymous) ARRAY

[ qw(a b c) ]

so the next

use 5.016;
use warnings;
use diagnostics;
my $x = [ qw(a b c) ];
say ref $x;  #ARRAY - the $x is an ARRAY reference, and
say $x->[1]; #prints "b", and
say [ qw(a b c) ]->[1]; #works too

but what happens now?

use 5.016;
use warnings 'all';
use diagnostics;
say ${[ qw(a b c) ]}[1];

it prints b, but

my $y = ${[ qw(a b c) ]};

is an error,

Not a SCALAR reference at pepe line 6 (#1)
    (F) Perl was trying to evaluate a reference to a scalar value, but found
    a reference to something else instead.  You can use the ref() function
    to find out what kind of ref it really was.  See perlref.

Uncaught exception from user code:
    Not a SCALAR reference at pepe line 17.

So, whats mean the contruction ${.... }

And the hint from the diagnostics is not very helpful, because how I should use the ref when I can't assign? What I missed from the perlref?

Upvotes: 6

Views: 909

Answers (3)

ikegami
ikegami

Reputation: 385647

${ EXPR1 }[ EXPR2 ] is an array index dereference. It returns the element at the index returned by EXPR2 of the array referenced by the reference returned by EXPR1.

${ $array_ref }[ ... ] is to array references as $array[...] is to arrays.


${ EXPR } that's not followed by [ or { is a scalar dereference. It returns the scalar referenced by the reference returned by EXPR.

${ $scalar_ref } is to scalar references as $scalar is to scalars.


As you can see, when dealing with a reference, you can use the same syntax as you normally would, except that you replace the name of the variables with {$ref} (keeping the leading sigil).

As such, @{ $array_ref } is to array references as @array is to arrays.

say @{[ qw(a b c) ]};

This is the essence of the chart in my earlier post Mini-Tutorial: Dereferencing Syntax. See also:


Oops, I thought you had

say ${[ qw(a b c) ]};   # Want to print a b c

You have

my $y = ${[ qw(a b c) ]};

You want

my $y = [ qw(a b c) ];

[] creates an array and a reference to that array, and returns the latter, kinda like

my $y = do { my @anon = qw(a b c); \@a };

Upvotes: 10

clt60
clt60

Reputation: 63902

With the

${$ar}[0]

you said to perl: take $ar as arrayref and return me 1st element from the array to what the reference $ar points.

With the construction

${$sr}

you saying to perl: take the $sr as SCALAR REF and return the value of the scalar to what the reference $sr points.

Therefore, the answer to your question from the comment: When the $ar is an array-ref, WHAT IS the ${$ar}? is:

When the $ar is an $array-ref, the ${$ar} is an ERROR,

because you said to perl - take the scalar-ref, but the $ar is NOT scalar-ref (it is arrayref).

The next example show your constructions clearly:

use 5.012;
use warnings;

my @arr = qw(a b c);
my $aref = \@arr;

my $myval = "VALUE";
my $sref = \$myval;

say $aref->[0];
say ${$aref}[0];
say ${$sref}; #your construction - here CORRECTLY points to an scalar

#say ${$aref} #ERROR because the ${$xxx} mean: take scalar ref, but the $aref is array ref.

Upvotes: 1

amon
amon

Reputation: 57600

Given an array @arr and an arrayref $aref = \@arr, then inside the following groups of expressions all lines are equivalent:

Accessing the whole array:

@ arr
@{$aref}

Accessing a single scalar in the array:

$ arr   [$i]
${$aref}[$i]
$ aref->[$i]

Accessing a slice of entries:

@ arr   [$i .. $j]
@{$aref}[$i .. $j]

(the spaces are included for alignment and are not recommended for actual code).

The ${}, @{}, … are circumfix dereference operators. However, accessing a single scalar changes the sigil from % or @ to $. Without references, this makes total sense. With them, it's just slightly complicated, until you read perlreftut (esp. the two reference usage rules).

Upvotes: 4

Related Questions