Skip Menu |

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

Report information
The Basics
Id: 17008
Status: resolved
Worked: 10 min
Priority: 0/
Queue: UNIVERSAL-can

People
Owner: chromatic [...] cpan.org
Requestors: martin [...] hybyte.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 1.00
  • 1.01
Fixed in: (no value)



Subject: can breaks exceptions, like $@->can
Below a two perl snippets, equal to each other, except for the usage of UNIVERSAL::isa. They are all valid method calls of can. however with UNIVERSAL::isa the calll dies. perl -wle 'use strict; eval { die bless {}, "main" }; print $@->can("x")' perl -wle 'use UNIVERSAL::can; use strict; eval { die bless {}, "main" }; print $@->can("x")' and a workaround: perl -wle 'use UNIVERSAL::can; use strict; eval { die bless {}, "main" }; my $a=$@; print $a->can("x")' Enviroment is freebsd, and perl 5.8.7 This is due to UNIVERSAL::can does not make a copy of $_[0], but works on the callers copy. In this case $@. Then can calls eval itself, $@ will be empty, and so will $_[0]. Solution: Either make a copy of $@. Or try to do a "local $@" before the eval?
Subject: patch [can breaks exceptions, like $@->can]
From: Martin
The following patch works for me *** UNIVERSAL/can.pm --- UNIVERSAL/can.pm *************** *** 25,33 **** goto &$orig if $recursing; goto &$orig unless _is_invocant( $_[0] ); ! my $can = eval { $_[0]->$orig( 'can' ) || 0 }; goto &$orig if $can == \&UNIVERSAL::can; local $recursing = 1; my $invocant = shift; --- 25,34 ---- goto &$orig if $recursing; goto &$orig unless _is_invocant( $_[0] ); ! my $can; ! { local $@; $can = eval { $_[0]->$orig( 'can' ) || 0 }; }; goto &$orig if $can == \&UNIVERSAL::can; local $recursing = 1; my $invocant = shift;
Good catch. Fixed in 1.02, which should be on the CPAN in a few minutes.