OK, so I have an object. The object keeps a reference to another object and passes unknown methods to that object. Sounds reasonable? The AUTOLOAD looks like this:
the attribute is set upon object creation and is never reset so this should work fine, yep? The inner object is implemented in XS. Still OK? Fine, so I have the object, I have tests, all tests for the XS object work both under Windows and Unix, the numerous tests for the outer one work under Windows, there's nothing OS specific as far as I can tell so everything should work fine, right?sub AUTOLOAD { (my $sub = $The::Class::Name::AUTOLOAD) =~ s/^.*:://; my $db = shift; $db->{dbh}->$sub(@_); }
Wrong. Under Unix all subtests pass and then the test script "creates core". Every. Single. One.
I turn the XS module's tracing on, everything looks OK. I add a plethora of debug prints into the XS modules DESTROY method, the last of them at the very last line of the function. Everything gets printed, then it crashes.
I undef the outer object at the end of a test script and put a debug print above and below. The first one is printed, the other is not. OK. So it must be something with the object destruction, but what??? There's nothing special in the outer object, no need to destroy anything explicitely, it doesn't even have it's own DESTROY method!
OK, so the XS module worked with its own (short) tests, maybe something inside got borked by the many tests of the outer one. Let's exit() the test script sooner. Crash. Let's exit() it just after the object creation. Crash! OK, OK, OK, let's undef the attribute explicitely from outside the object.
What??? What destroy? OK, let's see the line ...(in cleanup) Can't call method "DESTROY" on an undefined value at ... +at line ...
Yes, you guessed, the line was in the AUTOLOAD method. The outer object had no DESTROY method, so it was passed to the inner one. And then was called on the already destroyed object again. Kabooooom.
Not sure why did it work under Windows, maybe thanks to a different version of Perl (5.8.6 under Unix, 5.8.8 under Windows), but ... as soon as I made sure I never redirect the DESTROY method (and added a check that the inner object is actually there before redirecting anything to it) everything works. Oh well.
Jenda
Enoch was right!
Enjoy the last years of Rome.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Beware of object composition!
by JavaFan (Canon) on Feb 05, 2010 at 07:03 UTC | |
|
Re: Beware of object composition!
by merlyn (Sage) on Feb 05, 2010 at 18:23 UTC | |
by Jenda (Abbot) on Feb 05, 2010 at 19:12 UTC | |
|
Re: Beware of object composition!
by shmem (Chancellor) on Feb 07, 2010 at 12:28 UTC |