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

[perl #129208] map sometimes does and sometime does not copy vals

Thread Previous
From:
Father Chrysostomos via RT
Date:
September 6, 2016 18:18
Subject:
[perl #129208] map sometimes does and sometime does not copy vals
Message ID:
rt-4.0.24-14192-1473185875-1294.129208-15-0@perl.org
On Mon Sep 05 23:05:36 2016, zefram@fysh.org wrote:
> 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.

They are equivalent in that they return values that are referentially identical, such that \$_[0] == \shift.

> 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

The equivalence is what I’m looking for.

Either map’s return value should be referentially identical to the value returned from the block, or it should not be.  map should be consistent either way.  Make sense?

(Fixing this is just a matter of checking that the refcount is 1 before deciding to skip copying something already marked SvTEMP.)

> 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.

And the fact the the AvREAL flag on @_ makes a difference is a bug, too.

-- 

Father Chrysostomos


---
via perlbug:  queue: perl5 status: open
https://rt.perl.org/Ticket/Display.html?id=129208

Thread Previous


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