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:

sub AUTOLOAD { (my $sub = $The::Class::Name::AUTOLOAD) =~ s/^.*:://; my $db = shift; $db->{dbh}->$sub(@_); }
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?

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.

(in cleanup) Can't call method "DESTROY" on an undefined value at ... +at line ...
What??? What destroy? OK, let's see the 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.


In reply to Beware of object composition! by Jenda

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.