http://www.perlmonks.org?node_id=11120008

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

The link to the documentation is https://perldoc.perl.org/perlop.html#Assignment-Operators

"Similarly, a list assignment in list context produces the list of lvalues assigned to, and a list assignment in scalar context returns the number of elements produced by the expression on the right hand side of the assignment."

I don't understand. Can you monks please explain to me and give me examples of what this sentence means?

"Unlike in C, the scalar assignment operator produces a valid lvalue. Modifying an assignment is equivalent to doing the assignment and then modifying the variable that was assigned to."

I don't get it either. Please clarify to me I beg.

• Comment on Not understanding 2 sentences in perldoc

Replies are listed 'Best First'.
Re: Not understanding 2 sentences in perldoc
by choroba (Archbishop) on Jul 29, 2020 at 20:13 UTC
List assignment:
```my (\$x, \$y, \$z) = qw( 1 2 3 );

List assignment in list context produces a list of lvalues:

```(my (\$x, \$y, \$z) = qw( 1 2 3 )) = qw( a b c ); # \$x = 'a', \$y = 'b', \$
+z = 'c'.

List assignment in scalar context:

```print scalar (my (\$x, \$y, \$z) = qw( a b c d ));  # 4

Modifying a scalar assignment:

```(\$x = 12) =~ s/1/4/; print \$x;  # 42

map{substr\$_->[0],\$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
List assignment in list context produces a list of lvalues:

(my (\$x, \$y, \$z) = qw( 1 2 3 )) = qw( a b c ); # \$x = 'a', \$y = 'b', \$z = 'c'.

What is the lvalues here?
> What is the lvalues here?

(\$x, \$y, \$z) are after the first assignment ready for the second one.

Lvalue means left value of assignment (the recipient)

• lvalue

Term used by language lawyers for a storage location you can assign a new value to, such as a variable or an element of an array. The “l” is short for “left”, as in the left side of an assignment, a typical place for lvalues. An lvaluable function or expression is one to which a value may be assigned, as in pos(\$x) = 10 .

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

```#                  | inner assignment with a LHS (l) and RHS (r)
#      llllllllll..v...rrrrrrr                                       # \$x = 1,   \$y = 2,   \$z = 3.
(my (\$x, \$y, \$z) = ( 1, 2, 3 )) = ('a', 'b', 'c' );
#      llllllllll.................^..rrrrrrrrrrrrr                   # \$x = 'a', \$y = 'b', \$z = 'c'.
#                                 | outter assignment with a LHS (l) and RHS (r)
```
Slightly changed the internal scalar semantics by eliminating qw.
For my own edificiation, would we expect B::Deparse to have broken this down further? This was my first attempt to decompose it.
```perl -MO=Deparse -e '(my (\$x, \$y, \$z) = qw( 1 2 3 )) = qw( a b c )'
(my(\$x, \$y, \$z) = ('1', '2', '3')) = ('a', 'b', 'c');
-e syntax OK
```
Re: Not understanding 2 sentences in perldoc
by ikegami (Pope) on Jul 30, 2020 at 21:28 UTC

It means this

```my \$x = f();
my \$y = \$x;
can be written as
```my \$y = my \$x = f();
and
```my \$copy = \$str;
\$copy =~ s/\\/\\\\/g;
can be written as
```( my \$copy = \$str ) =~ s/\\/\\\\/g;

Very concise! ++

But he asked for lists, so

```my @x = f();
my @y = @x;

can be written as

my @y = my @x = f();

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

##### update
```  DB<39> sub f { 1..3}

DB<40> my @y = my @x = f(); print"@x,@y"
1 2 3,1 2 3
DB<41>

Well, the second passage was about scalar assignment. That's what I focused on. Your example completes the answer by addressing the first passage. Thanks.

Re: Not understanding 2 sentences in perldoc
by ikegami (Pope) on Jul 30, 2020 at 22:48 UTC
A list assignment gotcha
by jcb (Vicar) on Jul 30, 2020 at 02:01 UTC

There is one other surprise in here that I once found the hard way: plain assignment will operate on lists, but modifying assignments (+= in the example that I recall) will not — if you try to increment a group of values, only the last item in each list is affected.

That's because the (scalar) operator of an op= imposes scalar context on the lists and so only the last element of each list is affected:

```c:\@Work\Perl\monks>perl -wMstrict -le
"my (\$x, \$y, \$z) = (30, 40, 50);
(\$x, \$y, \$z) += (3, 4, 5);
print qq{\$x, \$y, \$z};
"
Useless use of a constant in void context at -e line 1.
Useless use of a constant in void context at -e line 1.
Useless use of private variable in void context at -e line 1.
Useless use of private variable in void context at -e line 1.
30, 40, 55
Raku can do these kinds of list operations; see Raku Programming/Meta Operators.

Update: I'm not aware that you can do this with pure lists in Perl 5, but it can certainly be done with arrays:

```c:\@Work\Perl\monks>perl -wMstrict -le
"my @ra = (30, 40, 50);
my @rb = ( 3,  4,  5);
;;
\$ra[\$_] += \$rb[\$_] for 0 .. \$#ra;
print qq{@ra};
"
33 44 55
And via List::MoreUtils::pairwise():
```c:\@Work\Perl\monks>perl -wMstrict -le
"use List::MoreUtils qw(pairwise);
use vars qw(\$a \$b);
;;
my @ra = (30, 40, 50);
my @rb = ( 3,  4,  5);
;;
my @rc = pairwise { \$a + \$b } @ra, @rb;
print qq{@rc};
"
33 44 55
or
```c:\@Work\Perl\monks>perl -wMstrict -le
"use List::MoreUtils qw(pairwise);
use vars qw(\$a \$b);
;;
my @ra = (30, 40, 50);
my @rb = ( 3,  4,  5);
;;
pairwise { \$a += \$b } @ra, @rb;
print qq{@ra};
"
33 44 55
(The  use vars qw(\$a \$b); statement quiets some warnings.)

Give a man a fish:  <%-{-{-{-<

Exactly — they look analogous, but they are not. The List::MoreUtils tricks are interesting, but actually wrap a loop iterating over arrays instead of being a true "vectorized" modifying assignment. There is probably something in PDL for this if your program does that kind of processing, but for a simple case with a list of Perl scalars, you need to use multiple statements.

> plain assignment will operate on lists, but modifying assignments (+= in the example that I recall) will not

If you really needed this, it could be done with a little syntactic sugar

something like

L(\$x,\$y,\$z) += L(1,2,3);

the trick would be to let L() ( for "list" ) return an object with overload ed operators (in scalar context) performing the side-effect

Tho I'm not sure if the RHS needs to be packed into an object too, but I assume += is imposing scalar context.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

A bit trickier than I originally thought. What I didn't expect was the need to use the :lvalue on both the listifier and constructor.
```#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

{   package L;
'+=' => sub {
my (\$self, \$inc) = @_;
\$_ += shift @\$inc for @\$self;
};
sub new :lvalue {
bless \$_[1], \$_[0]
}
}
sub L :lvalue { 'L'->new(\@_) }

my (\$x, \$y, \$z) = (10, 20, 30);
L(\$x, \$y, \$z) += L(3, 2, 1);
say "\$x \$y \$z";  # 13 22 31