Re: Not understanding 2 sentences in perldoc
by choroba (Archbishop) on Jul 29, 2020 at 20:13 UTC
|
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]
| [reply] [d/l] [select] |
|
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?
| [reply] [d/l] |
|
> 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)
See also perlglossary
- 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 .
| [reply] |
|
|
|
|
|
|
|
|
|
# | 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.
| [reply] [d/l] |
|
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
| [reply] |
Re: Not understanding 2 sentences in perldoc
by ikegami (Pope) on Jul 30, 2020 at 21:28 UTC
|
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;
Update: Added second example.
| [reply] [d/l] [select] |
|
my @x = f();
my @y = @x;
can be written as
my @y = my @x = f();
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>
| [reply] [d/l] [select] |
|
| [reply] |
Re: Not understanding 2 sentences in perldoc
by ikegami (Pope) on Jul 30, 2020 at 22:48 UTC
|
| [reply] |
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.
| [reply] [d/l] |
|
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: <%-{-{-{-<
| [reply] [d/l] [select] |
|
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.
| [reply] |
|
> 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.
| [reply] [d/l] |
|
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;
use overload
'+=' => 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
You can use [3, 2, 1] on the RHS, as well.
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
| [reply] [d/l] [select] |
|
|
|
Re: Not understanding 2 sentences in perldoc
by perlfan (Vicar) on Jul 29, 2020 at 20:59 UTC
|
>"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."
This means that you can use the product of inner assignment as the left hand side (lvalue) of an outer assignment operator (=), as has been demonstrated. | [reply] [d/l] |
|
Thank you all guys very much! The perl community is the best!
| [reply] |
|
It is. Sometimes it's a team sport like volleyball, some times it's American Gladiators. Get yourself a real account here, fool.
| [reply] |
|