http://qs321.pair.com?node_id=124449

mikeB has asked for the wisdom of the Perl Monks concerning the following question:

It seems Perl is cleaning up in "the wrong order" on my WinNT Perl 5.6.0 system. Below is a section of code from a module. The constructor creates a Win32::OLE object and stores a reference to it. When the destructor is called, that object is apparently already destroyed. I'm not sure how this can legitimately happen, as the module's instance data still holds a reference to the OLE object.

At the suggestion of someone in the CB (sorry... forgot who) I tried adding a global reference to the OLE object as an experiment to see if that would keep it around. That didn't seem to help.

What am I missing? Is there a way to make this work? Or am I barking up the wrong tree?

use Win32::OLE; sub new { # fileName my $self = {}; bless $self, shift; $self->{excel} = Win32::OLE->new("Excel.Application") or croak "Ca +n't start Excel: ", Win32::OLE->LastError, "\n"; return $self; } sub disconnect { my $self = shift; $self->{excel}->Quit if $self->{excel}; }

Replies are listed 'Best First'.
(tye)Re: non-deterministic destructors?
by tye (Sage) on Nov 10, 2001 at 00:18 UTC

    Globals ("package variables") get destroyed in a "random" order. Keep all of your objects in lexicals and this problem should go away. Though a module putting objects into globals would also be a problem. (This has been discussed here before. If anyone finds the previous threads, then post a note here and I'll do the same if I get around to searching.)

            - tye (but my friends call me "Tye")
      The object is being created as
      my $table = new ExcelTable(...);
      I try to avoid globals :)

        Yes, but if anyone holds a reference to that same object in a global or in something that is referenced by something that is referenced by something... that is in a global, then destruction will be delayed until the ominously named "global destruction phase", at which point objects are destroyed in a "random" order.

        For example, closures aren't cleaned up until "the end" (even if you no longer hold a reference to them since Perl itself creates a references loop when it creates closures -- this bug has been fixed but I don't think the fix is in a stable release of Perl yet). Or perhaps ExcelTable keeps a list of objects that it has created.

        You could use Devel::Peek to see the reference count of what $table refers to. That would give you a hint if something else is keeping a reference to it (or perhaps you have an XS bug that is leaving the reference count on the other object too low so that it actually is getting destroyed early, tho that seems unlikely -- such XS bugs usually leave the ref count too high, which could be another reason why destruction of your main object is delayed).

                - tye (but my friends call me "Tye")
Re: non-deterministic destructors?
by converter (Priest) on Nov 09, 2001 at 23:57 UTC

    It would be helpful if you'd list any warnings or error messages and the version number of the module. This will give others who'd like to look into the problem a place to start looking.

    I just noticed the following in Camel 3 ed. It may or may not be helpful:

    page 331:

    Objects are always destroyed in a separate pass before ordinary references. This is to prevent DESTROY methods from using references that have themselves been destroyed.

    conv