Skip Menu |

This queue is for tickets about the Class-Std CPAN distribution.

Report information
The Basics
Id: 14431
Status: open
Priority: 0/
Queue: Class-Std

People
Owner: Nobody in particular
Requestors: luke [...] daeron.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in:
  • 0.0.4
  • 0.0.9
  • 0.011
Fixed in: (no value)



Subject: subtle bug created by wrapping UNIVERSAL::can
Because of this module, I keep bumping into corners of Perl I hadn't explored yet :-) Today's discovery came after trying to figure out why the following failed: $ perl -wle 'use Config::Std; use Template::Timer;' Died at /Library/Perl/5.8.6/Template/Timer.pm line 63. The uses wouldn't fail if performed in the opposite order. Template::Timer looked too simple to give rise to any real weirdness, so I looked through Class::Std to see if anything unusual was going on, and came across the replacement of UNIVERSAL::can. And sure enough, the offending line in Template::Timer was a call to can() with a form I'd never seen before: my $super = __PACKAGE__->can("SUPER::$sub") or die; I didn't even know that was possible! The error introduced by Class::Std is, I think, that SUPER::whatever has a meaning based on the context of the call, not the class of the invocant. Class::Std, in wrapping UNIVERSAL::can, moves the context of the call to itself, which will never completely work, at least without some ugly hacking for this corner case. Since Template::Timer is using simple inheritance it seems it could be easily rewritten to be both less cryptic and compatible with Class::Std. But this feature could be pretty useful with multiple inheritance, and breaking unrelated code is obviously a bad thing... I have attached a test case that demonstrates the problem succinctly.
use strict; package A; sub foo { 1 } package B; our @ISA = 'A'; use Test::More tests => 2; BEGIN { is( B->can("foo"), B->can("SUPER::foo"), "can(SUPER::method) finds sub"); } use Class::Std; is( B->can("foo"), B->can("SUPER::foo"), "can(SUPER::method) after UNIVERSAL::can replaced" );
Date: Sat, 05 Nov 2005 10:28:12 -0800
To: bug-Class-Std [...] rt.cpan.org
Subject: Re: [cpan #14431] subtle bug created by wrapping UNIVERSAL::can
From: Damian Conway <thoughtstream [...] gmail.com>
RT-Send-Cc:
Show quoted text
> Today's discovery came after trying to figure out why the following failed: > $ perl -wle 'use Config::Std; use Template::Timer;' > Died at /Library/Perl/5.8.6/Template/Timer.pm line 63. > > The uses wouldn't fail if performed in the opposite order. > > Template::Timer looked too simple to give rise to any real weirdness, > so I looked through Class::Std to see if anything unusual was going > on, and came across the replacement of UNIVERSAL::can. And sure > enough, the offending line in Template::Timer was a call to can() with > a form I'd never seen before: > > my $super = __PACKAGE__->can("SUPER::$sub") or die; > > I didn't even know that was possible! The error introduced by > Class::Std is, I think, that SUPER::whatever has a meaning based on > the context of the call, not the class of the invocant. Class::Std, in > wrapping UNIVERSAL::can, moves the context of the call to itself, > which will never completely work, at least without some ugly hacking > for this corner case. Since Template::Timer is using simple > inheritance it seems it could be easily rewritten to be both less > cryptic and compatible with Class::Std. But this feature could be > pretty useful with multiple inheritance, and breaking unrelated code > is obviously a bad thing...
Fixed by rearranging the replacement C<UNIVERSAL::can()> so that it eventually does a: goto &{$real_can}; Thanks, Damian
From: Mark Blythe
This still seems to be broken as of Class::Std v0.08. Will the mentioned fix be published soon?
On Sun Apr 02 03:53:58 2006, guest wrote: Show quoted text
> This still seems to be broken as of Class::Std v0.08. Will the > mentioned fix be published soon?
fixed in 0.0.9 via rt 30833, thanks!
Show quoted text
> fixed in 0.0.9 via rt 30833, thanks!
Also, please reopen with details if this is in actuality not fixed in 0.0.9's UNIVERSAL::can fix, thanks!
I think this is still broken. I checked the unit test attached to this ticket and it fails in 0.0.9 and 0.011. I can give more details if you need them, but I think the attached test is an accurate description of my problem.