Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

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

by moritz (Cardinal)
on Oct 23, 2008 at 22:23 UTC ( [id://719177]=note: print w/replies, xml ) Need Help??


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

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).

Replies are listed 'Best First'.
Re^3: If you believe in Lists in Scalar Context, Clap your Hands
by chromatic (Archbishop) on Oct 24, 2008 at 08:27 UTC
    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.

        Sure, but you can also argue that 1, 2, 3, isn't a list of values but a list of expressions. Is this a list:

        my $x = ($y = 1), ($z = 2);

        How about this?

        s{\\}{\\\\}g, print

        Or this?

        foo => scalar param( 'foo' )

        It's difficult to tell without seeing the context... which makes me wonder if lists do exist, or if we should talk about the value of expressions instead.

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

        my @x = chomp <DATA>;

        Bingo, @x is gets a one-element list -- or at least, it's a list in list context and a scalar in scalar context. Tricky! Here's a mind-bender. What's this?

        1, 2, 3

        It could be a three-element list, in list context, or it could be a scalar and two void expressions (which get optimized away), in scalar context. In void context, it could be nothing.

        Update: Reworded one sentence.

        when used with a list, it returns the total number of characters chomped... and not a list (so, you are right that there is no "list context" to it.
        []s, HTH, Massa (κς,πμ,πλ)
Re^3: If you believe in Lists in Scalar Context, Clap your Hands
by TGI (Parson) on Oct 23, 2008 at 23:26 UTC

    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 ?

        I think the inner consistency you are missing is that operands aren't only values, they can be operations as well. The left = (the scalar assignment) has as its right operand not the "result of [the list] assignment", but rather the list assigment operation. And that operation, by virtue of being the right side of a scalar assignment, gets scalar context, and the "result" of a list assignment in scalar context is the number of elements on the right of the assignment. Does that help at all?
        The difference between
        $s1 = ($x, $y) = 0..11;
        and
        $s2 = ($x, $y)
        is that $s1 gets assigned the result of the list assignment operator, and $s2 gets assigned the result of the scalar comma operator. In neither case there's a list assigned to any of the $s? variables; in both cases the result of operators are assigned.

        But as long as you keep believing in the existence of lists in scalar context, you'll keep being confused.

Re^3: If you believe in Lists in Scalar Context, Clap your Hands
by JavaFan (Canon) on Oct 23, 2008 at 22:30 UTC
    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")

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2024-04-25 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found