Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight

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:


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 ?

Replies are listed 'Best First'.
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 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.


    _($_=" "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 salva (Abbot) 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 Krambambuli (Curate) 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 ./ 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 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;
      my @one = (7,2,3);
      (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.


        _($_=" "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 Random_Walk (Prior) 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


    Pereant, qui ante nos nostra dixerunt!


    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.


      _($_=" "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?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://615267]
Approved by marto
Front-paged by bart
[ambrus]: ething that's both cleanly organized and mostly automated.
LanX in train, bad connection
[Corion]: ambrus: Yeah - we're in that situation too, except that there is no time to do the reorganizing :-/
[LanX]: ... so my boss started a project with the newest sun servers and invited the traders to come on weekend to test it... and they were so pleased, that they forced him to keep it in production...
[ambrus]: Corion: sure, this is the long-term plan. The short term is that I have to run this ungodly mess to get results from the new input data today.
[Corion]: ambrus: Most of our "automation" is tied to process exit codes and a shell pipeline :-\
[LanX]: ... a week later they realized that one of the databases - which recorded how much the other banks due to this bank - was not correctly plugged
[ambrus]: Corion: I have no problem with exit codes and shell pipeline. My problem is that the current process requires a lot of manual intervention from me, including editing the source codes.
[ambrus]: (Also a lot of manual intervention by two or three other co-workers, who do other parts of the process.)
[ambrus]: Some of the manual part is unavoidable, but not all.

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (16)
As of 2017-03-29 11:49 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (350 votes). Check out past polls.