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

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

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 {\$_} 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 \$_ and shift to be equivalent in whether they yield an lvalue.
Which they're not:

\$ perl -lwe '\$x = 4; sub { \$_ = 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 \$_/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(\$_) { \$_ = 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

```