Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Not understanding 2 sentences in perldoc

by Anonymous Monk
on Jul 29, 2020 at 19:13 UTC ( #11120008=perlquestion: print w/replies, xml ) Need Help??

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)

        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 .

        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;

    Update: Added second example.

      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; 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]
Re: Not understanding 2 sentences in perldoc
by perlfan (Priest) 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.

      Thank you all guys very much! The perl community is the best!
        It is. Sometimes it's a team sport like volleyball, some times it's American Gladiators. Get yourself a real account here, fool.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11120008]
Approved by marto
Front-paged by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2020-09-29 11:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If at first I don’t succeed, I …










    Results (146 votes). Check out past polls.

    Notices?