Skip Menu |

This queue is for tickets about the UNIVERSAL-can CPAN distribution.

Report information
The Basics
Id: 25355
Status: resolved
Priority: 0/
Queue: UNIVERSAL-can

People
Owner: Nobody in particular
Requestors: bitcard [...] dumarchie.demon.nl
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.12
Fixed in: (no value)



Subject: Broken SUPER semantics
UNIVERSAL::can breaks SUPER semantics. See the attached test. I have also attached a patch that solves this issue. The patch to can.pm is based on the view that a subclass is allowed to know everything about its superclass. This includes knowledge about whether UNIVERSAL::can() can be used as a function. Also, I did see no other way to support SUPER semantics. I had to patch bad-input.t because my perl thinks that main->isa(''). I don't know whether this is a feature... Regards, Peter du Marchie van Voorthuysen
Subject: UNIVERSAL-can.patch
diff -ru UNIVERSAL-can-1.12\lib\UNIVERSAL\can.pm UNIVERSAL-can\lib\UNIVERSAL\can.pm --- UNIVERSAL-can-1.12\lib\UNIVERSAL\can.pm Sat Apr 01 07:15:10 2006 +++ UNIVERSAL-can\lib\UNIVERSAL\can.pm Fri Mar 09 15:38:45 2007 @@ -39,7 +39,7 @@ return _report_warning() unless defined $_[0]; # don't get into a loop here - goto &$orig if $recursing; + goto &$orig if $recursing || caller->isa($_[0]); # call an overridden can() if it exists local $@; diff -ru UNIVERSAL-can-1.12\t\bad-input.t UNIVERSAL-can\t\bad-input.t --- UNIVERSAL-can-1.12\t\bad-input.t Sat Apr 01 07:15:10 2006 +++ UNIVERSAL-can\t\bad-input.t Fri Mar 09 15:31:57 2007 @@ -1,5 +1,7 @@ #!perl +package test; # because main->isa('') + use strict; use warnings; Only in UNIVERSAL-can\t: SUPER-can.t
Subject: SUPER-can.t
use UNIVERSAL::can; use strict; use warnings; package MyClass; my @Caller; sub can { push @Caller, caller; } sub test { my ($invocant, $method) = @_; $invocant->SUPER::can($method); } package main; use Test::More tests => 2; my @Warning; local $SIG{__WARN__} = sub { push @Warning, @_ }; MyClass->test("foo"); is_deeply(\@Warning, [], "CLASS->SUPER::can(METHOD) does not give a warning"); is_deeply(\@Caller, [], "CLASS->SUPER::can(METHOD) does not invoke CLASS->can(METHOD)");
Thanks, applied for the 1.14 release.