http://www.perlmonks.org?node_id=1040854


in reply to Referring to an array without copying to a separate variable first

#!/usr/bin/perl use strict; use warnings; my $res = { 'objects'=>[ {'a'=>'1', b=>'2'} ] }; for my $elem ( @{$res->{objects}} ) { print $elem->{a}."\n"; print $elem->{b}."\n"; }
Note that @{$res->{objects}} and @$res->{objects} are not the same.

Replies are listed 'Best First'.
Re^2: Referring to an array without copying to a separate variable first
by LanX (Saint) on Jun 26, 2013 at 22:06 UTC
    little addendum:

    > Note that @{$res->{objects}} and @$res->{objects} are not the same.

    ... b/c of Perl's precedence rules:

    @$res->{objects} means @{$res}->{objects} which doesn't make sense.

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      "@$res->{objects} means @{$res}->{objects} which doesn't make sense."

      It doesn't make sense to me either but B::Deparse seems to know what's going on:

      $ perl -MO=Deparse,p -e '@{$res}->{objects}' @{$res;}->{'objects'}; -e syntax OK

      I suspect the ; after $res is the key but I'm not sure why. I shall have to give this some more thought.

      -- Ken

        > ... but B::Deparse seems to know what's going on: ...

        B::Deparse can't help here, cause it's a runtime error and not a syntax problem.

        > ... I suspect the ; after $res is the key ...

        The ';' you are seeing is an indicator that %{ } and alike are effectively do { } blocks plus dereferencing.

        lanx@nc10-ubuntu:~$ perl -e '$r={a=>1};print %{$r;},"\n"' a1 lanx@nc10-ubuntu:~$ perl -MO=Deparse,p -e '$r={a=>1};print %{$r;},"\n" +' $r = {'a', 1}; print %{$r;}, "\n"; -e syntax OK lanx@nc10-ubuntu:~$ perl -MO=Deparse,p -e 'print %{ $r={a=>1};$r; },"\ +n"' print %{$r = {'a', 1}; $r;}, "\n"; -e syntax OK lanx@nc10-ubuntu:~$ perl -e 'print %{ $r={a=>1};$r; },"\n"' a1

        Interesting, well spotted! =)

        UDPATE

        Reminds me of this old trick to have code executed within interpolation

        DB<100> print " @{ [ 1..10 ] } " 1 2 3 4 5 6 7 8 9 10

        maybe clearer

        DB<106> print " @{ $a++; [1..$a ] } " 1 DB<107> print " @{ $a++; [1..$a ] } " 1 2 DB<108> print " @{ $a++; [1..$a ] } " 1 2 3

        Cheers Rolf

        ( addicted to the Perl Programming Language)

      which doesn't make sense.

      Sure it does, $res just happens to be a hash

        > Sure it does, $res just happens to be a hash

        No it never does, since the code @{$res}->{objects} tries to dereference a hash-ref not an array.

        But interestingly this magically (?) works:

        DB<112> @a="a".."d" => ("a", "b", "c", "d") DB<113> @a->[2] => "c"

        aaaah! =)

        DB<114> use warnings; @a->[2] Using an array as a reference is deprecated ...

        Cheers Rolf

        ( addicted to the Perl Programming Language)