summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2012-06-22 13:34:49 -0500
committerJesse Luehrs <doy@tozt.net>2012-06-23 12:55:55 -0500
commit68b40612054cc4269bdb1112df64c078975b1467 (patch)
treef3ece84172a7c4bf4f0d17df1a0b664c12be3102
parent914077f0095913a3ac75894b4c3610cfa4b30150 (diff)
downloadperl-68b40612054cc4269bdb1112df64c078975b1467.tar.gz
all packages can do methods in UNIVERSAL [perl #47113]
Foo->can("can") should be true even if "package Foo" hasn't been seen yet (obviously, since that method call doesn't die with a method not found error).
-rw-r--r--t/op/universal.t11
-rw-r--r--universal.c2
2 files changed, 10 insertions, 3 deletions
diff --git a/t/op/universal.t b/t/op/universal.t
index 40f14ce1f0..01459dd795 100644
--- a/t/op/universal.t
+++ b/t/op/universal.t
@@ -10,7 +10,7 @@ BEGIN {
require "./test.pl";
}
-plan tests => 135;
+plan tests => 138;
$a = {};
bless $a, "Bob";
@@ -107,7 +107,7 @@ for ($p=0; $p < @refs; $p++) {
};
};
-ok ! UNIVERSAL::can(23, "can");
+ok UNIVERSAL::can(23, "can");
++${"23::foo"};
ok UNIVERSAL::can("23", "can"), '"23" can can when the pack exists';
ok UNIVERSAL::can(23, "can"), '23 can can when the pack exists';
@@ -167,7 +167,7 @@ if ('a' lt 'A') {
eval 'sub UNIVERSAL::sleep {}';
ok $a->can("sleep");
-ok ! UNIVERSAL::can($b, "can");
+ok UNIVERSAL::can($b, "can");
ok ! $a->can("export_tags"); # a method in Exporter
@@ -331,3 +331,8 @@ use warnings "deprecated";
@RT66112::T6::ISA = qw/RT66112::E/;
ok(RT66112::T6->isa('RT66112::A'), "modify \@ISA in isa (RT66112::T6 isa RT66112::A)");
}
+
+ok(Undeclared->can("can"));
+sub Undeclared::foo { }
+ok(Undeclared->can("foo"));
+ok(!Undeclared->can("something_else"));
diff --git a/universal.c b/universal.c
index 384d3071fc..383feaae00 100644
--- a/universal.c
+++ b/universal.c
@@ -369,6 +369,8 @@ XS(XS_UNIVERSAL_can)
}
else {
pkg = gv_stashsv(sv, 0);
+ if (!pkg)
+ pkg = gv_stashpv("UNIVERSAL", 0);
}
if (pkg) {