diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-09-03 23:33:48 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-09-04 08:27:31 -0700 |
commit | a14c24d0aff00806bd26ad296c7dc8ed2aed3f0a (patch) | |
tree | 0bcf20503a242fc74b5d43211cc9c9d998ac96c0 /toke.c | |
parent | 2578d12a1403dc84569782ef1290059d33317cab (diff) | |
download | perl-a14c24d0aff00806bd26ad296c7dc8ed2aed3f0a.tar.gz |
Fix our-sub method confusion
‘our $foo’ creates a lexical alias to a global symbol. That lexi-
cal alias is resolved during parsing. For instance, if you have
‘our $foo; package bar; $foo’, the last $foo is translated by the
parser into a ‘main::foo’ constant, which is then used for sym-
bol lookup.
A similar thing happens with ‘our subs’. In
‘our sub foo; package bar; foo()’, the foo() call is first translated
into main::foo, and then there are various checks to determine how to
handle this bareword.
Sometimes it is determined to be a method call, and that’s where
things go awry. For this name transformation should only happen when
we are going to call this sub. If the parser concludes that it is not
actually a sub call, then the original bareword as it appeared in the
source should be used. But that is not what was happening. As a con-
sequence, this code compiles down to F->main::f, rather than F->f.
use experimental "lexical_subs";
our sub f;
{package F}
f F;
__END__
Undefined subroutine &main::f called at - line 4.
And that it is actually doing a method call, not just f(F) can be dem-
onstrated by the fact that extra arguments can come after F without an
intervening comma:
use experimental "lexical_subs";
our sub f { warn "@_" };
{package F}
f F "g";
__END__
F g at - line 2.
And that inheritance works:
use experimental "lexical_subs";
@ISA = "Bar";
our sub f;
undef *f;
sub Bar'f { print "bark\n" }
{package F}
f F;
__END__
bark
This commit corrects the behaviour by discarding the translated
symbol and restoring the original bareword if it turns out it is a
method name.
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 9 |
1 files changed, 9 insertions, 0 deletions
@@ -6662,6 +6662,15 @@ Perl_yylex(pTHX) && (isIDFIRST_lazy_if(s,UTF) || *s == '$') && (tmp = intuit_method(s, lex ? NULL : sv, cv))) { method: + if (lex && !off) { + assert(cSVOPx(pl_yylval.opval)->op_sv == sv); + SvREADONLY_off(sv); + sv_setpvn(sv, PL_tokenbuf, len); + if (UTF && !IN_BYTES + && is_utf8_string((U8*)PL_tokenbuf, len)) + SvUTF8_on (sv); + else SvUTF8_off(sv); + } op_free(rv2cv_op); if (tmp == METHOD && !PL_lex_allbrackets && PL_lex_fakeeof > LEX_FAKEEOF_LOWLOGIC) |