2009/7/21 Bram <p5p@perl.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 :( ) Ah, you're right. The parser has this line : switch : label GIVEN '(' remember mydefsv mexpr ')' mblock where mydefsv is an empty rule that lexicalizes $_. But then the code I pasted above could probably be simplified. > 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...) Yes.Thread Previous | Thread Next