develooper Front page | perl.perl5.porters | Postings from July 2009

Re: [perl #67694] List::Util attaching to the wrong $_ when used inside given/when construct

Thread Previous | Thread Next
From:
Bram
Date:
July 21, 2009 03:24
Subject:
Re: [perl #67694] List::Util attaching to the wrong $_ when used inside given/when construct
Message ID:
20090721122426.89xnpi13284o0coc@horde.wizbit.be
Citeren Rafael Garcia-Suarez <rgarciasuarez@gmail.com>:

> 2009/7/21 Bram <p5p@perl.wizbit.be>:
>> This seem to happen because given creates a lexical $_. It also happens when
>> for/foreach is used with a lexical $_:
>
> Hmm what ? No, given does not create a lexical $_ :

I didn't look at the code only at the docs and the output :/

from perldoc perlsyn:
'given(EXPR) will assign the value of EXPR to $_ within the lexical  
scope of the block, so it's similar to do { my $_ = EXPR; ... }'

the output shows a different reference for $_ in the when block and in  
the s1 sub


> from pp_entergiven :
>
>     if (PL_op->op_targ == 0) {
>         SV ** const defsv_p = &GvSV(PL_defgv);
>         *defsv_p = newSVsv(POPs);
>         SAVECLEARSV(*defsv_p);
>     }
>     else
>         sv_setsv(PAD_SV(PL_op->op_targ), POPs);
>
> What happens, at first glance, it that List::Util always uses the
> global $_. (an "our $_" in the "first" block should solve the pb).

Then what does in create in pp_entergiven?
Doesn't it modify PL_defgv?
(I have to admit being not familiar enough with the code to really  
read/understand it :( )


Adding an our $_ does solve the problem:
With 's1 { our $_; print "\tblock:\t \$_ = " . \$_ . " (value: $_)";  
};' the output becomes:

Given/when block:
         when-1:  $_ = SCALAR(0x942d7f0) (value: 1)
         s1:      $_ = SCALAR(0x942d500) (value: a)
         block:   $_ = SCALAR(0x942d500) (value: a)
         when-2:  $_ = SCALAR(0x942d7f0) (value: 1)


But why is this be nessesary?
If given() does not create a lexical $_ then shouldn't the $_ in the  
block be the same as the global $_?

>
> We provide UNDERBAR and dUNDERBAR macros to access the current $_, be
> it lexical or global.
>
> However we don't have (yet) an API to localize the current $_ as
> needed in grep-like functions.
>
> I suppose that code from pp_grepstart could be copied in List::Util to
> solve the bug.

That would only work for the XS version right?
(There is also a Pure Perl version...)


Best regards,

Bram



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