needperlhelp has asked for the wisdom of the Perl Monks concerning the following question:

@l_tmp = (1,2,3,4); $l_ref = \@l_tmp; print $$l_ref[0]; # This works , by printing 1 $l_ref = \(1,2,3,4); print $$l_ref[0]; # This fails ( prints nothing )
Can some one explain what is that i miss in this code

Replies are listed 'Best First'.
Re: Reference on List & Arrays Difference
by shmem (Chancellor) on Mar 11, 2007 at 09:50 UTC
    $l_ref = \(1,2,3,4);
    Here you are taking a reference to the result of evaluating the list (1,2,3,4) in scalar context, which is 4:
    # perl -le '$l_ref = \(1,2,3,4); print $l_ref' SCALAR(0x8150310) # perl -le '$l_ref = \(1,2,3,4); print $$l_ref' 4

    so you end up with an anonymous scalar holding the value 4.

    You want to use

    $l_ref = [ 1,2,3,4 ];

    to create an anonymous array (or array reference).

    A list is not a perl data type, it's just some grouping of elements, so you can't create a reference to that. You can only take a reference to what comes out of evaluating that grouping expression, which is not an array in your case, but the number of elements inside the list result of the comma operations inside the parens.

    update: Corrected interpretation of what's inside the parens. Thanks, Anno.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      You wrote about this bit of code
      $l_ref = \(1,2,3,4);

      A list is not a perl data type, it's just some grouping of elements, so you can't create a reference to that. You can only take a reference to what comes out of evaluating that grouping expression, which is not an array in your case, ...

      Correct, and well said.

      ... but the number of elements inside the list.

      That's wrong. It's (a reference to) the last of the scalar expressions that were strung together with the scalar comma operator. Changing the code to

      $l_ref = \(1,2,3,99);
      makes the difference apparent.

      Anno

        Oh..! Thanks for correcting that. So the (1,2,3,4) is not even interpreted as a list, but as a grouping of operands and operators which evaluation results in the last (rightmost) operand.

        You never stop to learn...

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
        To elucidate further, \( 1, 2, 3, 4 ) is just short for ( \1, \2, \3, \4 ):
        $ perl -le' use Data::Dumper; @x = \( 4, 5, 6, 7 ); print Dumper \@x; ' $VAR1 = [ \4, \5, \6, \7 ]; $ perl -le' use Data::Dumper; @x = ( \4, \5, \6, \7 ); print Dumper \@x; ' $VAR1 = [ \4, \5, \6, \7 ];
        And the assignment to a scalar does the same thing with or without the backslash(es):
        $ perl -le' use Data::Dumper; $x = ( 4, 5, 6, 7 ); print Dumper $x; ' $VAR1 = 7; $ perl -le' use Data::Dumper; $x = \( 4, 5, 6, 7 ); print Dumper $x; ' $VAR1 = \7; $ perl -le' use Data::Dumper; $x = ( \4, \5, \6, \7 ); print Dumper $x; ' $VAR1 = \7;
Re: Reference on List & Arrays Difference
by Anonymous Monk on Mar 11, 2007 at 09:42 UTC