Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

array assignment with list operator , no parenthesis

by jesuashok (Curate)
on May 14, 2007 at 10:56 UTC ( #615267=perlquestion: print w/ replies, xml ) Need Help??
jesuashok has asked for the wisdom of the Perl Monks concerning the following question:

monks,

Apologies, if this has been discussed already.

use strict; my @one = 7,2,3; print "@one\n"; Output :- 7
I am very curious to know about the perl's internal behavior of the array assignment in the above code. How the Value 7 is assigned to the array, and why not 2 and 3 is not assigned to the array ?

Comment on array assignment with list operator , no parenthesis
Download Code
Re: array assignment with list operator , no parenthesis
by FunkyMonk (Canon) on May 14, 2007 at 11:16 UTC
Re: array assignment with list operator , no parenthesis
by salva (Monsignor) on May 14, 2007 at 11:18 UTC
    That's because the '=' operator has higher precedence than ','.

    Your expression is parsed as

    (my @one = 7), 2, 3;
Re: array assignment with list operator , no parenthesis
by shmem (Canon) on May 14, 2007 at 11:40 UTC
    Perl has the tools you can use to answer that question to yourself - apart from the docs (see perlop), B::Deparse is helpful:
    perl -MO=Deparse,-p -e 'my @one = 7,2,3; print "@one"' ((my(@one) = 7), '???', '???'); print("@one\n"); -e syntax OK

    From the extra grouping parens you can read the precedence. The '???' means that the expression it stands for has been optimized away.

    --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}
Re: array assignment with list operator , no parenthesis
by PreferredUserName (Pilgrim) on May 14, 2007 at 12:36 UTC
    As for why Perl has this little wart, it's because assigning a literal list to an array like that less common than saving the return value of a function for which you omit the parens. You can safely do this:
    $text = join "|", 1, 2, 3;
    but if assignment bound tighter than comma, that would annoyingly parse as:
    ($text = join "|"), 1, 2, 3;

      I'm not sure where you are going, but it seems the conclusion would be that
      my @one = 7,2,3;
      is
      my @one = (7,2,3);
      because
      (my @one = 7),2,3;
      would be annoying.

      The very post to which you replied shows this is untrue.
      my @one = 7,2,3;
      is the same as
      (my @one = 7),2,3;

      There is more than one operator represented by the comma. Your examples and therefore your conclusion are irrelevant to the OP's problem since you're not using the same operator. The OP's problem is that he used the comma operator where he wanted to use the list seperator, not one of precedence.

      Just like join forced a list in your example, the OP can force a list by adding parens around the would-be list. The parens do not change the precendence in this case. They change the parsing context, causing the comma to be parsed as a different operator.

      Update: Changed wording.
      Update: s/context/parsing context/, in response to shmem's reply.

        Not (quite) accurate. Consider
        ($foo) = (7,2,4); # list context - comma := list separator print $foo,"\n"; __END__ 7
        $foo = (7,2,4); # scalar context despite of parens - comma := 'C' co +mma print $foo,"\n"; __END__ 4
        $foo = (7,2,4) x 3; # comma := 'C' comma, 'x' operates on scalar print $foo,"\n"; __END__ 444
        @foo = (7,2,4) x 3; # comma := list separator, 'x' operates on list print @foo,"\n"; __END__ 724724724

        Parens are just grouping, thus for precedence. They do not provide list context. The list context in

        @foo = (7,2,4);

        is enforced by the LHS of the expression. But it is perfectly legal to assign a single scalar to an array. The parens are for precedence first, and then, that being clear, the comma is disambiguated as a list separator, as enforced by the LHS.

        --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}
Re: array assignment with list operator , no parenthesis
by bones (Acolyte) on May 14, 2007 at 12:40 UTC
    the precedence of "=" is bigger than the ","
Re: array assignment with list operator , no parenthesis
by Krambambuli (Deacon) on May 14, 2007 at 13:25 UTC
    Making systematic use of
    use strict; use warnings;
    would spoil the pleasure of letting questions like this showing up... :)
    With warnings enabled, the fun of debugging the issue in a later stage would have vanished, as the message shown during compilation:
    Useless use of a constant in void context at ./test.pl line ...
    is obviously much less of a quest.
      I scrolled fast over the replies and finally found what I expected that some will answer this way. ++ Krambambuli

      Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: array assignment with list operator , no parenthesis
by Random_Walk (Parson) on May 14, 2007 at 14:04 UTC

    You are not copying an array into your array. You are putting in the result of the operation 7,2,3 which is 7 @one = 7,2,3 which due to precedence is evaluated as (my @one = 7),2,3 as previously explained in this thread. To get the array I think you want in there:

    use strict; use warnings; use strict; my @one = (7,2,3); print "@one\n"; Output :- 7 2 3

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!

    update

    shmem pointed out my sloppy summary of this problem. I was concentrating on what I thought he wanted to achieve and lost sight of the true explanation.
      You are putting the result of the operation 7,2,3 which is 7.

      No, it is not. Consider:

      perl -le 'sub foo { 7,2,3 } $foo = foo(); print $foo' 3

      It's a precedence problem as other posters pointed out.

      update Well, actually... the above example is misleading, since the comma operator is used in list context here - subroutines always return lists (if not declared with a single ($) as prototype, that is). And evaluating a list in scalar context gives its last element - which is just what the comma operator does ;-) A better example might be

      print not 1,0; print $/; __END__ 1

      The not operator gets the 0 and turns it to 1.

      --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}

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://615267]
Approved by marto
Front-paged by bart
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2014-07-23 04:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (133 votes), past polls