This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make sort bareword respect lexical subs
authorFather Chrysostomos <sprout@cpan.org>
Tue, 16 Sep 2014 20:10:38 +0000 (13:10 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 16 Sep 2014 20:56:20 +0000 (13:56 -0700)
—something I completely missed when implementing them.

op.c
t/op/lexsub.t

diff --git a/op.c b/op.c
index 9b1ef8c..4ace886 100644 (file)
--- a/op.c
+++ b/op.c
@@ -9971,6 +9971,33 @@ Perl_ck_sort(pTHX_ OP *o)
            kid->op_next = kid;
            o->op_flags |= OPf_SPECIAL;
        }
+       else if (kid->op_type == OP_CONST
+             && kid->op_private & OPpCONST_BARE) {
+           char tmpbuf[256];
+           STRLEN len;
+           PADOFFSET off;
+           const char * const name = SvPV(kSVOP_sv, len);
+           *tmpbuf = '&';
+           assert (len < 256);
+           Copy(name, tmpbuf+1, len, char);
+           off = pad_findmy_pvn(tmpbuf, len+1, SvUTF8(kSVOP_sv));
+           if (off != NOT_IN_PAD) {
+               if (PAD_COMPNAME_FLAGS_isOUR(off)) {
+                   SV * const new =
+                       newSVhek(HvNAME_HEK(PAD_COMPNAME_OURSTASH(off)));
+                   sv_catpvs(new, "::");
+                   sv_catsv(new, kSVOP_sv);
+                   SvREFCNT_dec_NN(kSVOP_sv);
+                   kSVOP->op_sv = new;
+               }
+               else {
+                   OP * const new = newOP(OP_PADCV, 0);
+                   new->op_targ = off;
+                   cUNOPx(firstkid)->op_first = new;
+                   op_free(kid);
+               }
+           }
+       }
 
        firstkid = OP_SIBLING(firstkid);
     }
index 91bb15f..81addda 100644 (file)
@@ -7,7 +7,7 @@ BEGIN {
     *bar::is = *is;
     *bar::like = *like;
 }
-plan 141;
+plan 142;
 
 # -------------------- Errors with feature disabled -------------------- #
 
@@ -111,6 +111,14 @@ sub F::h { 4242 }
 our sub j;
 is j
   =>, 'j', 'name_of_our_sub <newline> =>  is parsed properly';
+sub _cmp { $a cmp $b }
+sub bar::_cmp { $b cmp $a }
+{
+  package bar;
+  our sub _cmp;
+  package main;
+  is join(" ", sort _cmp split //, 'oursub'), 'u u s r o b', 'sort our_sub'
+}
 
 # -------------------- state -------------------- #
 
@@ -384,9 +392,7 @@ is runperl(switches => ['-lXMfeature=:all'],
   state sub x { is +(caller 0)[3], 'x', 'state sub name in caller' }
   x
 }
-sub _cmp { $a cmp $b }
 {
-  local $::TODO = ' ';
   state sub _cmp { $b cmp $a }
   is join(" ", sort _cmp split //, 'lexsub'), 'x u s l e b',
     'sort state_sub LIST'
@@ -749,7 +755,6 @@ is runperl(switches => ['-lXMfeature=:all'],
   x
 }
 {
-  local $::TODO = ' ';
   my sub _cmp { $b cmp $a }
   is join(" ", sort _cmp split //, 'lexsub'), 'x u s l e b',
     'sort my_sub LIST'