Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Re: If you believe in Lists in Scalar Context, Clap your Hands

by chromatic (Archbishop)
on Oct 23, 2008 at 22:12 UTC ( #719176=note: print w/ replies, xml ) Need Help??


in reply to If you believe in Lists in Scalar Context, Clap your Hands

What's wrong with the notion of a List in Scalar Context ?

There are many ways to produce a list in Perl, but there is no general rule for the result of evaluating a list in scalar context. There is a general rule for the result of evaluating an array in scalar context, which is why it's important to distinguish between lists and arrays.


Comment on Re: If you believe in Lists in Scalar Context, Clap your Hands
Re^2: If you believe in Lists in Scalar Context, Clap your Hands
by moritz (Cardinal) on Oct 23, 2008 at 22:23 UTC
    but there is no general rule for the result of evaluating a list in scalar context.

    The general rule is that the last item of the list is returned, but there might be exceptions (as always ...).

    The OP mentions that $scalar = 'a' .. 'z' is an error, but that's really a feature of the range operator, not of "list is scalar context".

    The only exception I'm aware of is $r = () = 4..5, where the number of items is returned rather than the the last item. But by my definition above that would actually be an array, not a list, because you can assign to it.

    Are there cases where something that's unambiguously a list (and not an array) returns anything else than the last item?

    (And I'm not talking about functions that are context sensitive via wantarray either).

      The only exception I'm aware of is $r = () = 4..5, where the number of items is returned rather than the the last item. But by my definition above that would actually be an array, not a list, because you can assign to it.
      But it ain't an array - you're assigning to a(n empty) sequence of scalars. And that $r ends up with the number of items has nothing to do with lists in scalar context. It's a feature of the assignment operator. Since () is an empty list, the second '=' is the list assignment operator. And the list assignment operator in scalar context returns the number of elements on its right hand side. (See "man perlop")

      On $r = () = 4..5; vs @r = () = 4..5;

      It's useful to look at this snippet to help understand what's happening:

      $r = ($x, $y) = (1..10);
      • Assignment is right associative.
      • ($x,$y) = 1..10 sets $x, and $y and returns in scalar context returns the number of elements on the right hand side (in this case, 10). In a list context it will return a list of lvalues assigned to.
      • So now we have reduced the above to $r = 10 which needs no explanation.
      • Note that it doesn't matter what is in the middle term, as long as it puts the right hand assignment in list context.

      If we look at @r = () = 1..10 we will see that the right hand assignment assigns to no lvalues and so returns an empty list. And thus @r is empty.


      TGI says moo

        Perhaps I don't fully understand right associativity.

        Consider:

        $r = () = 0..11 ; $s = ($x, $y) = 0..11 ;
        which I thought meant that the 0..11 would be evaluated in List Context, and then assigned to the lvalues in lists () and ($x, $y) -- the rightmost assignment first.  Then the result of that assignment would be assigned to <c>$r and $s this being a scalar assignment. The actual result is that both $r and $s are set to 12. This seems to imply that the first, list, assignment assigns the entirity of (0, 1, ...11) to the intermediate list, irrespective of the number of lvalues it contains. Then the length of that list is assigned to $r. This last step is consistent with the well known Array in Scalar Context... though () doesn't look like an array to me... but I'm willing to believe.

        Of course:

        $s = ($x, $y) ;
        assigns $y to $s. But I'm willing to accept that this is quite different from the above. I just don't yet see how.

        As you say, if we then look at:

        @r = () = 0..11 ; @s = ($x, $y) = 0..11 ;
        we find that @r is set to the empty list and @s to the two element list (0, 1). I confess this is more what I expected. The result of the second assignment depends on the result of the first (rightmost).

        Is it just me ? Is this in fact consistent at some deeper level I don't yet understand ?

      Are there cases where something that's unambiguously a list (and not an array) returns anything else than the last item?

      A regular expression match with the /g flag, in scalar context.

      A map or grep expression in scalar context.

      The empty list my $x = () = some_expression; construct, in scalar context.

      split, chomp, ....

      A bare hash. (Want to argue over what a list is? Is it multiple, comma-separated expressions or something that pushes one or more items onto the internal stack? I'm not sure lists even exist as a language-level construct in Perl 5.)

        One could argue that built-ins like map and grep don't return a list in scalar context, but are context sensitives themselves, so they are not fit for explaining "a list in scalar context". Likewise a regex match with /g.

        chomp???   How did chomp get in there?   It never returns a list.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://719176]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (9)
As of 2014-12-26 01:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (163 votes), past polls