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:
Rafael Garcia-Suarez
Date:
July 24, 2009 14:10
Subject:
Re: [perl #67694] List::Util attaching to the wrong $_ when used inside given/when construct
Message ID:
b77c1dce0907241410s7ffd8d4br584deb7d8dc561e5@mail.gmail.com
2009/7/24 Rafael Garcia-Suarez <rgarciasuarez@gmail.com>:
> 2009/7/24 Dave Mitchell wrote:
>> So if I've understood this correctly, given() adds a lexical $_ to the
>> scope, and there's a bug in List::Util::first in that it doesn't work with
>> a lexical $_? So not a bug in given/smartmatch?
>
> Yes, although I'm not 100% sure that pp_given does exactly the right
> thing with the pad. List::Util::first needs to assign to the lexical $_
> in the pad if there is one.

Yes, the patch below solves your reduced test case, the one with grep
and first, but doesn't solve the original problem, which denotes
probably another bug in pp_given (that constructs a lexical $_ without
a padmy op.)

Graham, would you consider an improved version of the patch below for
List::Util, to make first work with lexical $_ ? I don't think there
are other areas in List::Util that need a similar modification.

--- a/ext/List-Util/ListUtil.xs
+++ b/ext/List-Util/ListUtil.xs
@@ -329,16 +329,25 @@ CODE:
     I32 gimme = G_SCALAR;
     SV **args = &PL_stack_base[ax];
     CV *cv;
+    PADOFFSET padoff_du = find_rundefsvoffset();
+    bool has_global_underbar = padoff_du == NOT_IN_PAD
+       || PAD_COMPNAME_FLAGS_isOUR(padoff_du);

     if(items <= 1) {
        XSRETURN_UNDEF;
     }
     cv = sv_2cv(block, &stash, &gv, 0);
     PUSH_MULTICALL(cv);
-    SAVESPTR(GvSV(PL_defgv));
+    if (has_global_underbar)
+       SAVESPTR(GvSV(PL_defgv));
+    else
+       SAVESPTR(PAD_SVl(padoff_du));

     for(index = 1 ; index < items ; index++) {
-       GvSV(PL_defgv) = args[index];
+       if (has_global_underbar)
+           GvSV(PL_defgv) = args[index];
+       else
+           PAD_SVl(padoff_du) = args[index];
        MULTICALL;
        if (SvTRUE(*PL_stack_sp)) {
          POP_MULTICALL;

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