summaryrefslogtreecommitdiff
path: root/t/mro
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-11-28 18:04:01 -0800
committerFather Chrysostomos <sprout@cpan.org>2012-11-29 09:11:31 -0800
commit4e52a9b69e39f85d6a5d7ac598c61ff0b00f94ee (patch)
tree0ad7b7828f9733b88b28a3fed6799beb1492f4af /t/mro
parent3d460042b1251a4b5e3b583fa6be358554dd3bcc (diff)
downloadperl-4e52a9b69e39f85d6a5d7ac598c61ff0b00f94ee.tar.gz
Clear method caches when unwinding local *foo=*method
It was already working for those cases where *foo contained a sub before and after localisation. For those cases where *foo had no sub but localised assignment gave it one, method caches were not being reset on scope exit. case SAVEt_GP in scope.c:leave_scope needs to look at both GPs (glob pointer, or list of glob slots), both from before and after the unlo- calisation. If either has a sub, method caches need to be cleared. This does not yet fix local *foo = sub {}, but I added a to-do test for it. (This is more complicated, as localisation happens in two seperate steps, the glob slot localisation storing no pointers to the glob itself on the savestack.)
Diffstat (limited to 't/mro')
-rw-r--r--t/mro/method_caching.t10
1 files changed, 10 insertions, 0 deletions
diff --git a/t/mro/method_caching.t b/t/mro/method_caching.t
index d574cc9a22..d691926941 100644
--- a/t/mro/method_caching.t
+++ b/t/mro/method_caching.t
@@ -36,6 +36,16 @@ my @testsubs = (
sub { is(MCTest::Derived->foo(0), 5); },
sub { sub FFF { $_[1]+7 }; local *MCTest::Base::foo = *FFF; is(MCTest::Derived->foo(0), 7); },
sub { is(MCTest::Derived->foo(0), 5); },
+ sub { { local *MCTest::Base::can = sub { "tomatoes" };
+ MCTest::Derived->can(0); }
+ local $::TODO = " ";
+ is(MCTest::Derived->can("isa"), \&UNIVERSAL::isa,
+ 'removing method when unwinding local *method=sub{}'); },
+ sub { sub peas { "peas" }
+ { local *MCTest::Base::can = *peas;
+ MCTest::Derived->can(0); }
+ is(MCTest::Derived->can("isa"), \&UNIVERSAL::isa,
+ 'removing method when unwinding local *method=*other'); },
sub { sub DDD { $_[1]+8 }; *MCTest::Base::foo = *DDD; is(MCTest::Derived->foo(0), 8); },
sub { *ASDF::asdf = sub { $_[1]+9 }; *MCTest::Base::foo = \&ASDF::asdf; is(MCTest::Derived->foo(0), 9); },
sub { undef *MCTest::Base::foo; eval { MCTest::Derived->foo(0) }; like($@, qr/locate object method/); },