Search code examples
listperloperator-precedencescalarcomma-operator

List context and the comma operator in Perl


Having some significant confusion about what it means to "evaluate in list context", specifically related to the comma operator. In the linked perlop doc, it says: In list context, it's just the list argument separator, and inserts both its arguments into the list. However, the code

@y = 9, 8, 7, 6;
say @y, ', ', scalar @y;

gives output 9, 1. This respects the fact that, when used as a binary operator on scalar values (?), the comma operator , has lower precedence that the assignment = operator. But since I'm assigning to the list @y, shouldn't the right hand side of the assignment be evaluated in list context and, by the above quote, treat the comma simply as a separator?

I suspect that I just don't truly understand what it "evaluate in list context" means, precisely...


Solution

  • If you turn on warnings like you should, perl will give you some hints as to what's going on:

    #!/usr/bin/env perl
    use warnings;
    use strict;
    use feature qw/say/;
    
    my @y = 9, 8, 7, 6;
    say @y, ', ', scalar @y;
    

    running it shows

    Useless use of a constant (8) in void context at foo.pl line 6.
    Useless use of a constant (7) in void context at foo.pl line 6.
    Useless use of a constant (6) in void context at foo.pl line 6.
    9, 1
    

    @y = 9, 8, 7, 6 is an example of the comma operator in scalar context, and, as you noted, precedence rules. It's parsed as four different sub-expressions separated by commas: first @y = 9 assigns a single-element list to @y, and then the expressions 8, 7 and 6, all of which do nothing and generate warnings, and the whole thing would return 6 if there was anything to return to. If you want to assign a list to the variable, that list needs to be in parenthesis:

    my @y = (9, 8, 7, 6); # Or qw/9 8 7 6/ etc.