develooper Front page | perl.perl5.porters | Postings from September 2016

Re: [perl #129208] map sometimes does and sometime does not copyvals

Thread Previous | Thread Next
From:
Zefram
Date:
September 6, 2016 06:05
Subject:
Re: [perl #129208] map sometimes does and sometime does not copyvals
Message ID:
20160906060504.GO7097@fysh.org
Father Chrysostomos wrote:
>I would expect these two to be equivalent:
>
>$ ./perl -Ilib -le '$x = 4; sub {\@_; for (map {$_[0]} 1) { $_=3 } }->($x); print $x'
>4
>$ ./perl -Ilib -le '$x = 4; sub {\@_; for (map {shift} 1) { $_=3 } }->($x); print $x'
>3

Not sure why you'd expect them to be equivalent.  You're basically asking
for $_[0] and shift to be equivalent in whether they yield an lvalue.
Which they're not:

$ perl -lwe '$x = 4; sub { $_[0] = 3; }->($x); print $x'
3
$ perl -lwe '$x = 4; sub { shift = 3; }->($x); print $x'
Can't modify shift in scalar assignment at -e line 1, near "3;"
Execution of -e aborted due to compilation errors.

However, these two methods of using $_[0]/shift disagree on which one
yields an lvalue.  Furthermore, shift yields something lvalue enough to
get an equivalence out of it:

$ perl -lwe '$x = 4; sub { ${\shift} = 3; }->($x); print $x'
3
$ perl -le '$x = 4; sub {\@_; for (map {${\shift}} 1) { $_=3 } }->($x); print $x'
4

Then there's a third obvious way of using the maybe-lvalue that yields
different results again:

$ perl -lwe '$x = 4; sub { for($_[0]) { $_ = 3; } }->($x); print $x'
3
$ perl -lwe '$x = 4; sub { for(shift) { $_ = 3; } }->($x); print $x'
3
$ perl -lwe '$x = 4; sub { for(${\shift}) { $_ = 3; } }->($x); print $x'
3

So it's consistently inconsistent.

-zefram

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About