summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pp_hot.c16
-rw-r--r--t/op/method.t20
2 files changed, 33 insertions, 3 deletions
diff --git a/pp_hot.c b/pp_hot.c
index 550ab1a8c6..084f4a244f 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -3075,6 +3075,19 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
if (SvROK(sv))
ob = MUTABLE_SV(SvRV(sv));
else if (!SvOK(sv)) goto undefined;
+ else if (isGV_with_GP(sv)) {
+ if (!GvIO(sv))
+ Perl_croak(aTHX_ "Can't call method \"%"SVf"\" "
+ "without a package or object reference",
+ SVfARG(meth));
+ ob = sv;
+ if (SvTYPE(ob) == SVt_PVLV && LvTYPE(ob) == 'y') {
+ assert(!LvTARGLEN(ob));
+ ob = LvTARG(ob);
+ assert(ob);
+ }
+ *(PL_stack_base + TOPMARK + 1) = sv_2mortal(newRV(ob));
+ }
else {
/* this isn't a reference */
GV* iogv;
@@ -3125,8 +3138,7 @@ S_method_common(pTHX_ SV* meth, U32* hashp)
/* if we got here, ob should be an object or a glob */
if (!ob || !(SvOBJECT(ob)
- || (SvTYPE(ob) == SVt_PVGV
- && isGV_with_GP(ob)
+ || (isGV_with_GP(ob)
&& (ob = MUTABLE_SV(GvIO((const GV *)ob)))
&& SvOBJECT(ob))))
{
diff --git a/t/op/method.t b/t/op/method.t
index 821f60468d..d206fc75fe 100644
--- a/t/op/method.t
+++ b/t/op/method.t
@@ -13,7 +13,7 @@ BEGIN {
use strict;
no warnings 'once';
-plan(tests => 142);
+plan(tests => 146);
@A::ISA = 'B';
@B::ISA = 'C';
@@ -490,6 +490,24 @@ is "3foo"->CORE::uc, '3FOO', '"3foo"->CORE::uc';
{ no strict; @{"3foo::ISA"} = "CORE"; }
is "3foo"->uc, '3FOO', '"3foo"->uc (autobox style!)';
+# *foo vs (\*foo)
+sub myclass::squeak { 'eek' }
+eval { *myclass->squeak };
+like $@,
+ qr/^Can't call method "squeak" without a package or object reference/,
+ 'method call on typeglob ignores package';
+eval { (\*myclass)->squeak };
+like $@,
+ qr/^Can't call method "squeak" on unblessed reference/,
+ 'method call on \*typeglob';
+*stdout2 = *STDOUT; # stdout2 now stringifies as *main::STDOUT
+sub IO::Handle::self { $_[0] }
+# This used to stringify the glob:
+is *stdout2->self, (\*stdout2)->self,
+ '*glob->method is equiv to (\*glob)->method';
+sub { $_[0] = *STDOUT; is $_[0]->self, \$::h{k}, '$pvlv_glob->method' }
+ ->($::h{k});
+
# Test that PL_stashcache doesn't change the resolution behaviour for file
# handles and package names.
SKIP: {