From 1d6df9f86ed4c2dd82004200f6de623daf22bf5e Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Sun, 20 May 2012 14:55:08 -0700 Subject: [PATCH] overload.pm: Allow :: in method names MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit According to overload’s documentation, ‘[v]alues specified as strings are interpreted as method names.’ But it behaves differently if the string contains a double colon: use overload q\""\=>"bar::baz"; @bar::ISA = foo; sub foo::baz{a} warn bless[] __END__ Undefined subroutine &bar::baz called at - line 4. But apostrophes work as documented: use overload q\""\=>"bar'baz"; @bar::ISA = foo; sub foo::baz{a} warn bless[] __END__ a at - line 4. I can’t see how the treatment of ::, introduced in a60067777, is not a bug, though the method logic looks intentional: + if (not ref $sub and $sub !~ /::/) { I suspect it was one of those things that was just not thought through. The pre-a60067777 logic was in gv.c, and treated strings containing package separators just like any other strings: switch (SvTYPE(sv)) { default: if (!SvROK(sv)) { if (!SvOK(sv)) break; gv = gv_fetchmethod(stash, SvPV(sv, na)); if (gv) cv = GvCV(gv); break; } cv = (CV*)SvRV(sv); --- lib/overload.pm | 2 +- lib/overload.t | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/overload.pm b/lib/overload.pm index 8954551..ed69440 100644 --- a/lib/overload.pm +++ b/lib/overload.pm @@ -42,7 +42,7 @@ sub OVERLOAD { warnings::warnif("overload arg '$_' is invalid") unless $ops_seen{$_}; $sub = $arg{$_}; - if (not ref $sub and $sub !~ /::/) { + if (not ref $sub) { $ {$package . "::(" . $_} = $sub; $sub = \&nil; } diff --git a/lib/overload.t b/lib/overload.t index fed261d..7657010 100644 --- a/lib/overload.t +++ b/lib/overload.t @@ -48,7 +48,7 @@ package main; $| = 1; BEGIN { require './test.pl' } -plan tests => 5051; +plan tests => 5053; use Scalar::Util qw(tainted); @@ -2297,6 +2297,20 @@ is eval {"$a"}, overload::StrVal($a), 'fallback is inherited by classes that have their own overloading' or diag $@; +# package separators in method names +{ + package mane; + use overload q\""\ => "bear::strength"; + use overload bool => "bear'bouillon"; +} +@bear::ISA = 'food'; +sub food::strength { 'twine' } +sub food::bouillon { 0 } +$a = bless[], mane::; +is eval { "$a" }, 'twine', ':: in method name' or diag $@; +is eval { !$a }, 1, "' in method name" or diag $@; + + { # undefining the overload stash -- KEEP THIS TEST LAST package ant; use overload '+' => 'onion'; -- 2.7.4