Scalar vs List Assignment Operator

Solution 1:

The symbol = is compiled into one of two assignment operators:

  • A list assignment operator (aassign) is used if the left-hand side (LHS) of a = is some kind of aggregate.
  • A scalar assignment operator (sassign) is used otherwise.

The following are considered to be aggregates:

  • Any expression in parentheses (e.g. (...))
  • An array (e.g. @array)
  • An array slice (e.g. @array[...])
  • A hash (e.g. %hash)
  • A hash slice (e.g. @hash{...})
  • Any of the above preceded by my, our or local

There are two differences between the operators.

Context of Operands

The two operators differ in the context in which their operands are evaluated.

  • The scalar assignment evaluates both of its operands in scalar context.

    # @array evaluated in scalar context.
    my $count = @array;
    
  • The list assignment evaluates both of its operands in list context.

    # @array evaluated in list context.
    my @copy = @array;
    

    # @array evaluated in list context.
    my ($first) = @array;
    

Value(s) Returned

The two operators differ in what they return.

  • The scalar assignment ...

    • ... in scalar context evaluates to its LHS as an lvalue.

      # The s/// operates on $copy.
      (my $copy = $str) =~ s/\\/\\\\/g;
      
    • ... in list context evaluates to its LHS as an lvalue.

      # Prints $x.
      print($x = $y);
      
  • The list assignment ...

    • ... in scalar context evaluates to the number of scalars returned by its RHS.

      # Only dies if f() returns an empty list.
      # This does not die if f() returns a
      # false scalar like zero or undef.
      my ($x) = f() or die;
      

      # $counts gets the number of scalars returns by f().
      my $count = () = f();
      
    • ... in list context evaluates to the scalars returned by its LHS as lvalues.

      # Prints @x.
      print(@x = @y);