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

Re: [perl #116577] multicall breaks lexicality of variables

Thread Previous | Thread Next
From:
Dave Mitchell
Date:
February 3, 2016 15:33
Subject:
Re: [perl #116577] multicall breaks lexicality of variables
Message ID:
20160203153327.GE3962@iabyn.com
On Wed, Jan 30, 2013 at 07:05:50PM +0000, Dave Mitchell wrote:
> On Tue, Jan 29, 2013 at 11:46:25AM -0800, Zefram wrote:
> > $ cat t0.pl
> > use List::Util qw(reduce);
> > our @q;
> > sub ggg {
> > 	my $x = $a;
> > 	push @q, \$x;
> > 	1;
> > }
> > sub fff { reduce \&ggg, 1, 2, 3; }
> > fff();
> > fff();
> > print $_,"\n" for @q;
> > $ perl t0.pl
> > SCALAR(0x1f52fc0)
> > SCALAR(0x1f52fc0)
> > SCALAR(0x1f53128)
> > SCALAR(0x1f53128)
> > $
> > 
> > ggg() is only getting one $x variable per invocation of reduce(),
> > whereas it should get one per invocation of ggg().  This seems to be
> > specific to the multicall mechanism (of which reduce() is the exemplar).
> 
> Looks like MULTICALL doesn't do a SAVE/LEAVE or equivalent around each
> function call: so all the clearing up (of lexical vars, local() etc)
> onky happens at the end of the reduce, in POP_MULTICALL.
> 
> I guess for correctness-over-performance's sake it should (although
> it will need to special-case calling /(?{})/, which is documented
> as accumulating local()s).
> 
> I note that sort(), which inspired MULTICALL, *does* pop the save stack
> after each call.

...

> I meant ENTER/LEAVE of course.

Having thought about this some more while revamping the context system,
I've realised that it should be the responsibility of the caller of
MULTICALL (i.e. the XS code) to do any savestack freeing, rather than
MULTICALL itself.  Otherwise, return values from the code block may get
freed by MULTICALL before the caller has had the opportunity to examine
that return value for e.g. truthiness. For example:

    @b = first { my $x = ....;  $x } @b

where $x gets freed during leave_scope().

So this is a bug/limitation in List::Util.

-- 
print+qq&$}$"$/$s$,$a$d$g$s$@$.$q$,$:$.$q$^$,$@$a$~$;$.$q$m&if+map{m,^\d{0\,},,${$::{$'}}=chr($"+=$&||1)}q&10m22,42}6:17a2~2.3@3;^2dg3q/s"&=~m*\d\*.*g

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