in reply to Scalar Vs. List context

Here are some rules of thumb:

Best, beth

Update struck out push and pop. Pop needs an actual array, not just a list e.g. pop @x or pop @$y as noted by jwkrahn below. The same applies to the first parameter of push as well. This is because both modify the contents of an address in memory rather than simply process a set of elements in sequence.

Replies are listed 'Best First'.
Re^2: Scalar Vs. List context
by jwkrahn (Abbot) on Jul 11, 2009 at 19:11 UTC
    The most commonly used functions expecting list context include push, pop,

    pop does not impose list context.   pop only accepts one argument, an array, and that is in scalar context.

    Update: on the other hand, push does impose a list context on everything after the initial array argument.

      pop only accepts one argument, an array, and that is in scalar context.

      Depending on how you look at it, it's either evaluated in list context (technical reality) or neither since it's not evaluated as an array would in list and scalar context (practical reality).

      In no way is it evaluated in scalar context like you claim.

        I'm not sure it even gets to the point of evaluation :-). At least in Perl 5.8.8 attempts to pass a first parameter without an @ sigal produces compilation errors. You don't even need strictures to produce them:
        our @x; sub foo { print "wantarray? ", wantarray?1:0, "\n"; push @x, (1,2,3); return @x; } pop foo();

        generates

        Type of arg 1 to pop must be array (not subroutine entry) at Monks/Sni +ppet.pm line 7, near ");" Execution of Monks/Snippet.pm aborted due to compilation errors.

        The same compilation error results if one tries to use a subroutine to generate the first parameter of push as well. Replacing pop foo() with push foo(), 4 results in

        Type of arg 1 to push must be array (not subroutine entry) at Monks/Sn +ippet.pm line 7, near "4;" Execution of Monks/Snippet.pm aborted due to compilation errors.

        Best, beth

        $ perl -le'print prototype "CORE::pop"' ;\@

        A reference is a scalar and pop's first argument is a scalar reference to an array.

Re^2: Scalar Vs. List context
by ikegami (Patriarch) on Jul 12, 2009 at 07:15 UTC

    array and list elements: these are implicitly in list context.

    Not true. Every expression can be evaluated in any context. The context in which the expression is evaluated is determined by the operator to which the expression is an operand.

    Expressions that are list elements are no exception. The list operator decides the context of its operands based on its context:

    @a = (1,2,3,4); # list, list, list, list $a = (1,2,3,4); # void, void, void, scalar

    Expressions that are arrays are no exception.

    @b = @a; # @a is evaluated in list context. $c = @a; # @a is evaluated in scalar context. @a; 1; # @a is evaluated in void context.
      Expressions that are list elements are no exception. The list operator decides the context of its operands based on its context:

      @a = (1,2,3,4); # list, list, list, list
      $a = (1,2,3,4); # void, void, void, scalar

      Your second example does not have any "list elements" because you can't have a list in scalar context.

        Not so. You're considering different definitions of "list" as equivalent.

        A list value can't be evaluated in scalar context. Or any context. They aren't operators, so they can't be evaluated. They exist on the stack.

        The list operator, on the other hand, can be evaluated in any context. Just like every other operator (as far as I know).

        >perl -MO=Concise -e"@a = (1,2,3,4);" ... - <1> ex-list lKP ->8 <-- "l" for list context ...
        >perl -MO=Concise -e"$a = (1,2,3,4);" ... 5 <@> list sKP ->6 <-- "s" for scalar context ...
        >perl -MO=Concise -e"(1,2,3,4); 1" ... 4 <@> list vKP ->5 <-- "v" for void context ...

        A less ambiguous wording of the statement you made is: An operator can't evaluate to (return) a list in scalar context.

        A list operator can be evaluated in scalar context, but it must evaluate to a scalar in scalar context

        Often repeated, but what do you call  ( 1 , 2 , 3 , 4 );? :D
          A reply falls below the community's threshold of quality. You may see it by logging in.
      Hmmm.
      use strict; use warnings; sub foo { print "wantarray? ", wantarray?1:0, "\n"; return wantarray? (1,2,3) : 's-s-sc-scalar'; } my @x =('a','b', foo(), 'c'); print "\@x=(@x)\n";

      prints

      wantarray? 1 @x=(a b 1 2 3 c)

      Looks like list context to me.

      Best,beth

        You only showed that it can be evaluated in list context. Why did you ignore my snippet which showed how it can be called in scalar and void context?

        sub foo { print "wantarray? ", wantarray?1:0, "\n"; } my @x =(foo(),foo(), foo()); my $x =(foo(),foo(), foo());
        wantarray? 1 wantarray? 1 wantarray? 1 wantarray? 0 wantarray? 0 wantarray? 0