in reply to Re^6: when is destroy function called
in thread when is destroy function called

roboticus:

Thanks for the explanation. As a test, I augmented the example I gave above with an equivalent function in C. (This was my first experience using Inline::C. To call the Perl sub from within C, I copied the example in the section “Calling Perl from C” of the Inline::C-Cookbook.)

#! perl use strict; use warnings; $| = 1; use Inline C => <<'END_C'; void baz(SV* foo_ref) { printf("Begin baz()\n"); fflush(stdin); dSP; ENTER; SAVETMPS; XPUSHs(sv_2mortal(newSVpvf("Plus an extra line"))); PUTBACK; call_pv("destruct", G_DISCARD); printf("Before FREETMPS\n"); fflush(stdin); FREETMPS; LEAVE; printf("-End- baz()\n"); fflush(stdin); } END_C { package Foo; sub new { my ($class, $num) = @_; my $self = { id => $num, }; return bless $self, $class; } sub DESTROY { my ($self) = @_; print 'Foo::DESTROY(', $self->{id}, ")\n"; } } my $foo1 = Foo->new('first'); my $foo2 = Foo->new('second'); bar($foo1); print "Back in main (1)\n"; baz($foo2); print "Back in main (2)\n"; sub bar { print "Begin bar()\n"; destruct($_[0]); print "-End- bar()\n"; } sub destruct { undef $_[0]; }

Output:

22:55 >perl 552c_SoPW.pl Begin bar() Foo::DESTROY(first) -End- bar() Back in main (1) Begin baz() Foo::DESTROY(second) Before FREETMPS -End- baz() Back in main (2) 22:56 >

From which it seems that the object is destroyed — meaning its reference count has fallen to zero — before the FREETMPS macro is reached. In which case the addition of the object to the sub’s call stack has not caused its reference count to be incremented? (Or am I simply misunderstanding here?)

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Replies are listed 'Best First'.
Re^8: when is destroy function called
by roboticus (Chancellor) on Mar 06, 2013 at 17:19 UTC
    Athanasius:

    Your code and analysis look alright with me. But I'll have to dig more to go much further. I may have to download your code this evening and give it a try. I'm kind of curious if not marking them as mortal would cause them to die in the FREETMPS area.

    It's pretty darned interesting, though. Hopefully someone with good internals knowledge will chime in. (bulk88, you there?)

    Update: I reworded it a little.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Mortals are freeded at the next ";" or next "}" scope end. Not sure about scope opens("{"). DESTROYs will run when the ";" is executed, not at commas and not at sub calls (callee gets a new mortal scope, i am talking about caller scope) in the statement. This can cause headaches when you assign a new obj to a scalar that held a ref to an old obj, depending on the design of the class/api/library, the old obj can change global state set by new obj, so when you do something that involves global state, you wont see the action of new obj, but of old obj.