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

Thinking of the following. Have a LIST

qw(abc); 

assign the LIST to anonymous (anonymous) ARRAY

 [ qw(abc) ] 

so next

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

but what is happening now?

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

he prints b but

 my $y = ${[ qw(abc) ]}; 

- 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 what is the construction of $ {....}

  • It "works" in say (prints the second element of an anonymous array), but doesn't understand why
  • but cannot assign it to a variable

And the help from diagnostics doesn’t help much, because how should I use ref when I can’t assign? What did I miss from perlref ?

+6
source share
3 answers

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

${ $array_ref }[ ... ] are $array[...] references, since $array[...] are arrays.


${ EXPR } , which does not follow [ or { , is a scalar dereferencing. It returns the scalar referenced by the link returned by EXPR .

${ $scalar_ref } refers to scalar links since $scalar refers to scalars.


As you can see, when working with a link, you can use the same syntax as usual, except that you replace the variable name with {$ref} (keeping the leading sigil).

Thus, @{ $array_ref } refers to arrays of links, since @array refers to arrays.

 say @{[ qw(abc) ]}; 

This is the essence of the diagrams in my previous post Mini-tutorial: The dereferencing syntax . See also:


Oops, I thought you had

 say ${[ qw(abc) ]}; # Want to print abc 

You have

 my $y = ${[ qw(abc) ]}; 

Do you want to

 my $y = [ qw(abc) ]; 

[] creates an array and a link to this array and returns the last one, like

 my $y = do { my @anon = qw(abc); \@a }; 
+10
source

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

Access to the entire array:

 @ arr @{$aref} 

Access to one scalar in an array:

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

Access to a fragment of records:

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

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

${} , @{} , ... are workaround dereferencing operators. However, access to one scalar changes the sigil from % or @ to $ . Without links, this makes full sense. With them, it's a little complicated until you read perlreftut (especially the two rules for using links).

+4
source

Via

 ${$ar}[0] 

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

When building

 ${$sr} 

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

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

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

because you said perl to take scalar-ref, but $ ar is not scalar ref (this is arrayref).

The following example clearly shows your constructs:

 use 5.012; use warnings; my @arr = qw(abc); 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. 
+1
source

Source: https://habr.com/ru/post/944933/


All Articles