How Perl Links Work

Can someone explain the push statement in the following Perl code to me? I know how push perl works, but I can't figure out what the first argument is in the next push command. I am trying to interpret someone's script. I tried print "@a\n"; but he only printed ARRAY(0x9aa370) , which makes me think that the push does nothing. Any help is appreciated. Thanks!

 my @a = (); my $b = 10; my $c = 'a'; push(@{$a[$b]}, $c); 
+5
source share
3 answers

Let it break.

The meaning of @{...} is understood from "Using Links" in perlref

Wherever you place an identifier (or chain of identifiers) as part of the name of a variable or routine, you can replace the identifier with a block that returns a link of the correct type.

So inside the {... } block it is better to work with an array reference. You have $a[$b] , the @a element at index $b , so the element must be arrayref.

Then @{...} splits it and push into the new $c element. In general, $c copied to the (single) element of the anonymous array whose reference is @a in the index $b array @a .

And the key part: since there is really no arrayref †, auto-activation is triggered and created. Since there are no elements in indices preceding $b they are also created with the value undef .

Now please work through

when using perlref linked at the beginning for full reference.


With complex data structures, it is useful to be able to see them, and there are tools for this. The most commonly used is the main Data :: Dumper , and here is an example with Data :: Dump

 perl -MData::Dump=dd -wE'@ary = (1); push @{$ary[3]}, "ah"; dd \@ary' 

with exit

  [1, undef, undef, ["ah"]]

where [] inside indicates arrayref, and its only element is the string ah .


More precisely, the undef scalar is dereferenced, and since this occurs in the context of lvalue, autovivitation is ongoing. Thanks ikegami for the comment. See for example this post with its links.

+12
source

We start with the following two statements:

  • @a starts as an empty array with no elements.
  • $b to 10.

Now look at this construction:

@{$a[$b]}

To understand what we can start in the middle: $a[$b] index element 10 of @a array.

Now we can work from there: @{...} considers its contents as a reference to an array. Therefore, @{$a[$b]} treats the contents of element 10 of @a as a reference to an anonymous array. That is, the scalar value contained in $a[10] is a reference to an array.

Now the layer in push:

push @{$a[$b]}, $c;

In the anonymous array specified in element 10 @a , you push the value of $c , which is the character "a". You can access this item as follows:

my $value = $a[10]->[0]; # character 'a'

Or contraction,

my $value = $a[10][0];

If you moved another value to @{$a[10]} , you will have access to it at:

my $other_value = $a[10][1];

But what about $a[0] through $a[9] ? You only press the value in $a[$b] , which is equal to $a[10] . Perl automatically expands the array to accommodate this 11th element ( $a[10] ), but leaves the value in $a[0] through $a[9] as undef . You mentioned that you tried this:

print "@a\n";

Interpolating an array into a string causes its elements to be printed with a space between them. So you have not seen this:

ARRAY(0xa6f328)

Did you see that:

ARRAY(0xa6f328)

... because there were ten spaces before the 11th element, containing an array reference.

If you used a script with use warnings at the top, you would see this instead:

 Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. Use of uninitialized value in join or string at scripts/mytest.pl line 12. ARRAY(0xa6f328) 

... or something very similar.

Your structure now looks like this:

@a = (undef,undef,undef,undef,undef,undef,undef,undef,undef,undef,['a'])

If you ever want to take a look at the data structure rather than using simple printing, follow these steps:

 use Data::Dumper; print Dumper \@a; 
+3
source

I had a discussion about this yesterday here

what does this mean that @a is an array

 $a[$b] 

- the cell in the array syntax @{} helps perl understand that the cell in question is an array, so you can perform push / pop operations on it.
if you do

 use Data::Dumper; print Dumper \@a; 

you should see something like:

 $VAR1 = [ undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, [ 'a' ] ]; 

as you can see, the 11th cell is an array containing the letter "a" as the only value
a push operation on an empty cell could also be written as:

 $a[$b] = [$c] 
+1
source

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


All Articles