diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-01-10 13:23:34 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-01-10 13:28:07 -0800 |
commit | a289ef89aea304cdebfa085e4451b1c02cb33648 (patch) | |
tree | fe69a0f5a42fdcb453ed6d97d99912cbe2d2139b | |
parent | d29a1dbb963b505f2020c99fdcc6a99d14c5f206 (diff) | |
download | perl-a289ef89aea304cdebfa085e4451b1c02cb33648.tar.gz |
[perl #24237] @& should not stop $& from working
Mentioning $& in a program slows everything down, because it force
regular expressions to do a pre-match copy.
It used to happen for any symbol named &, e.g., @& and %&. This was
changed in commit b4a9608f339, but that commit did not take into
account that the code path in question is only followed on creation of
the *& glob.
It should still be applying magic to $&, even if it is not setting
PL_sawampersand. The other place in gv_fetchpvn_flags that magical-
ises scalars (which currently handles %- %+ %! $] and @ISA), should
also turn on PL_sawampersand for $&.
All of the above applies to $' and $` as well.
-rw-r--r-- | gv.c | 13 | ||||
-rw-r--r-- | t/op/magic.t | 10 |
2 files changed, 18 insertions, 5 deletions
@@ -1650,8 +1650,14 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, else if (*name == '-' || *name == '+') require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0); } - if ((sv_type==SVt_PV || sv_type==SVt_PVGV) && *name == '[') + if (sv_type==SVt_PV || sv_type==SVt_PVGV) { + if (*name == '[') require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0); + else if (*name == '&' || *name == '`' || *name == '\'') { + PL_sawampersand = TRUE; + (void)GvSVn(gv); + } + } } else if (len == 3 && sv_type == SVt_PVAV && strnEQ(name, "ISA", 3) @@ -1859,14 +1865,13 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, case '&': /* $& */ case '`': /* $` */ case '\'': /* $' */ - if ( + if (!( sv_type == SVt_PVAV || sv_type == SVt_PVHV || sv_type == SVt_PVCV || sv_type == SVt_PVFM || sv_type == SVt_PVIO - ) { break; } - PL_sawampersand = TRUE; + )) { PL_sawampersand = TRUE; } goto magicalize; case ':': /* $: */ diff --git a/t/op/magic.t b/t/op/magic.t index adbdad60d9..6ddf2d8071 100644 --- a/t/op/magic.t +++ b/t/op/magic.t @@ -5,7 +5,7 @@ BEGIN { chdir 't' if -d 't'; @INC = '../lib'; require './test.pl'; - plan (tests => 150); + plan (tests => 153); } # Test that defined() returns true for magic variables created on the fly, @@ -180,6 +180,14 @@ is $&, 'bar'; is $', 'baz'; is $+, 'a'; +# [perl #24237] +for (qw < ` & ' >) { + fresh_perl_is + qq < \@$_; q "fff" =~ /(?!^)./; print "[\$$_]\\n" >, + "[f]\n", {}, + "referencing \@$_ before \$$_ etc. still saws off ampersands"; +} + # $" @a = qw(foo bar baz); is "@a", "foo bar baz"; |