[Bioperl-l] Grrrr. Another subtle overloading bug ...

Steve Chervitz stevechervitz@yahoo.com
Wed, 9 Jan 2002 23:59:26 -0800 (PST)


Hilmar Lapp wrote:
> > Aaron J Mackey wrote:
> > > % perl -l
> use Bio::Root::Root;
> my $obj = new Bio::Root::Root;
> eval {
> $obj->throw(-class => Bio::Root::Exception, -text =>
"foobar")
> };
> if($@) {
> print "Thrown!"
> }
> ^D
> Thrown!
> Same here, and:
> nereis-4: bioperl-live 13:54 118> perl --version
> This is perl, version 5.005_03 built for i586-linux
> So, it's not really 5.005 <-> 5.6.x. Hmm.

Was Error.pm installed when you ran this test? I
suspect not. In this case, Bio::Root::Root::throw()
reverts to its original behavior of putting a plain
old string into $@ instead of an Error object. 

I tested it out on 5.004_04 with Error.pm installed
and it works (i.e., prints "Thrown!"). So, you can use
an eval{} to handle a Error.pm thrown exception with
that version of perl.

My guess is that it won't work starting with 5.005,
based on this note from the perl 5.005 delta docs:

"die() now accepts a reference value, and $@ gets set
to that value in exception traps. This makes it
possible to propagate exception objects. This is an
undocumented experimental feature."

Anyway, I did some more digging and I'm pleased to
report that I figured it out and there's a simple
solution.

Turns out that Error.pm overloads numeric operations
to call Error::value(), and this is triggered by
if($@). So if you didn't have a -value parameter when
you created the Error object, Error::value() returns
undef and if($@) fails. 

The simple fix is for Bio::Root::Root::throw() to
check whether or not a -value parameter was supplied,
and if not (as when calling throw('string')), create a
non-zero dummy value before calling Error::throw(). 
I've got a fix for this that I'll commit soon.

Steve


__________________________________________________
Do You Yahoo!?
Send FREE video emails in Yahoo! Mail!
http://promo.yahoo.com/videomail/