map and grep weren't working correctly with lexical $_ in
Rafael Garcia-Suarez [Sun, 8 Feb 2004 21:21:28 +0000 (21:21 +0000)]
scalar context, because pp_mapwhile and pp_grepwhile were using
their target as a temporary slot to store the return value.

p4raw-id: //depot/perl@22289

pp_ctl.c
pp_hot.c
t/op/mydef.t

index 42d63c6..c5f802a 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -954,8 +954,15 @@ PP(pp_mapwhile)
        (void)POPMARK;                          /* pop dst */
        SP = PL_stack_base + POPMARK;           /* pop original mark */
        if (gimme == G_SCALAR) {
-           dTARGET;
-           XPUSHi(items);
+           if (PL_op->op_private & OPpGREP_LEX) {
+               SV* sv = sv_newmortal();
+               sv_setiv(sv, items);
+               PUSHs(sv);
+           }
+           else {
+               dTARGET;
+               XPUSHi(items);
+           }
        }
        else if (gimme == G_ARRAY)
            SP += items;
index e884e2d..ccfbf41 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -2294,8 +2294,15 @@ PP(pp_grepwhile)
        (void)POPMARK;                          /* pop dst */
        SP = PL_stack_base + POPMARK;           /* pop original mark */
        if (gimme == G_SCALAR) {
-           dTARGET;
-           XPUSHi(items);
+           if (PL_op->op_private & OPpGREP_LEX) {
+               SV* sv = sv_newmortal();
+               sv_setiv(sv, items);
+               PUSHs(sv);
+           }
+           else {
+               dTARGET;
+               XPUSHi(items);
+           }
        }
        else if (gimme == G_ARRAY)
            SP += items;
index 0770e78..485f843 100644 (file)
@@ -5,7 +5,7 @@ BEGIN {
     @INC = '../lib';
 }
 
-print "1..64\n";
+print "1..66\n";
 
 my $test = 0;
 sub ok ($$) {
@@ -118,6 +118,12 @@ $_ = "global";
     ok( $x eq '1globallocal-2globallocal', 'map without {}' );
 }
 {
+    for my $_ (1) {
+       my $x = map $_, qw(a b);
+       ok( $x == 2, 'map in scalar context' );
+    }
+}
+{
     my $buf = '';
     sub tgrep1 { /(.)/; $buf .= $1 }
     my $_ = 'y';
@@ -142,6 +148,12 @@ $_ = "global";
     ok( $_ eq 'local', '...but without extraneous side-effects' );
 }
 {
+    for my $_ (1) {
+       my $x = grep $_, qw(a b);
+       ok( $x == 2, 'grep in scalar context' );
+    }
+}
+{
     my $s = "toto";
     my $_ = "titi";
     $s =~ /to(?{ ok( $_ eq 'toto', 'my $_ in code-match # TODO' ) })to/