diff options
author | Father Chrysostomos <sprout@cpan.org> | 2010-11-11 06:12:00 -0800 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2010-11-11 09:35:19 -0800 |
commit | af16de9fb95af5577c9af62f59b791ea3a98d2b9 (patch) | |
tree | cdf7a02ac40e867211c0e2c747ef81570f847403 | |
parent | 8951c461a5079d86be33a432491eda98c24dc397 (diff) | |
download | perl-af16de9fb95af5577c9af62f59b791ea3a98d2b9.tar.gz |
[perl #79024] Bleadperl 80ebaca breaks OVID/Class-Trait-0.31.tar.gz
Commit 80ebaca actually exposed an existing bug that Class::Trait was
really close to triggering already:
undef *ISA; # @ISA no longer magical
Class::Trait’s tests just happened not to call ->isa before making any
changes to @ISA.
Now that the meta->isa cache is created immediately,
Class::Trait fails.
This bug can be reproduced in earlier perls by putting an ->isa call
right after the undef:
undef *{"Extra::TSpouse::ISA"};
'Extra::TSpouse'->isa('Class::Trait::Base');
unshift @{"Extra::TSpouse::ISA"}, Class::Trait::Base;
warn Extra::TSpouse->isa('Class::Trait::Base'); # something's wrong
This commit modifies gv_fetchpvn_flags to magicalise @ISA whenever it
is fetched.
-rw-r--r-- | gv.c | 4 | ||||
-rw-r--r-- | t/mro/basic.t | 14 |
2 files changed, 17 insertions, 1 deletions
@@ -1219,6 +1219,10 @@ 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); } + else if (len == 3 && sv_type == SVt_PVAV + && strnEQ(name, "ISA", 3) + && (!GvAV(gv) || !SvSMAGICAL(GvAV(gv)))) + gv_magicalize_isa(gv); } return gv; } else if (no_init) { diff --git a/t/mro/basic.t b/t/mro/basic.t index 353352bb61..1ecfd213a0 100644 --- a/t/mro/basic.t +++ b/t/mro/basic.t @@ -3,7 +3,7 @@ use strict; use warnings; -BEGIN { require q(./test.pl); } plan(tests => 49); +BEGIN { require q(./test.pl); } plan(tests => 50); require mro; @@ -300,3 +300,15 @@ is(eval { MRO_N->testfunc() }, 123); main->do; is $output, 'parentparent2', '@main::ISA is magical'; } + +{ + # Undefining *ISA, then modifying @ISA + # This broke Class::Trait. See [perl #79024]. + {package Class::Trait::Base} + no strict 'refs'; + undef *{"Extra::TSpouse::ISA"}; + 'Extra::TSpouse'->isa('Class::Trait::Base'); # cache the mro + unshift @{"Extra::TSpouse::ISA"}, 'Class::Trait::Base'; + ok 'Extra::TSpouse'->isa('Class::Trait::Base'), + 'a isa b after undef *a::ISA and @a::ISA modification'; +} |