Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Is possible to force the execution of a END block at runtime, without need to start global destruction?

by broquaint (Abbot)
on May 21, 2004 at 03:06 UTC ( #355166=note: print w/ replies, xml ) Need Help??


in reply to Is possible to force the execution of a END block at runtime, without need to start global destruction?

If you've got a recent enough version of perl (5.7+ IIRC) then you can use some B magic to access END blocks e.g

use B; sub B::exec_ENDs { my $pkg = caller; $_->object_2svref->() for grep { $_->GV->STASH->NAME eq $pkg } B::end_av->ARRAY; } { package foo; sub pretend_to_leave { B->exec_ENDs(); print "I'll go get my coat ...\n"; } END { print "... another END block\n" } END { print "foo: this will be followed by " } } foo->pretend_to_leave(); END { print "main: Right, I'm outta here\n" } __output__ foo: this will be followed by ... another END block I'll go get my coat ... main: Right, I'm outta here foo: this will be followed by ... another END block
So there I've created a subroutine (that I've snuck into B) that will execute the END blocks for the current package.
HTH

_________
broquaint


Comment on Re: Is possible to force the execution of a END block at runtime, without need to start global destruction?
Download Code
Re: Re: Is possible to force the execution of a END block at runtime, without need to start global destruction?
by gmpassos (Priest) on May 21, 2004 at 04:41 UTC
    Wow, thanks, this is a nice point to start. But I need to avoid that the END blocks that I have called at runtime won't be called on global destruction. At least this B code have a way to find the right END block in the list for a package, than I can overwrite them with a null END block.

    Many thanks.

    Graciliano M. P.
    "Creativity is the expression of the liberty".

Re: Re: Is possible to force the execution of a END block at runtime, without need to start global destruction?
by gmpassos (Priest) on May 23, 2004 at 02:40 UTC
    Just to end the node, here's a XS function that I made that return a reference to the CODE of the END blocks:
    void get_end_sub( pkg ) char * pkg PREINIT: CV *cv_end ; PPCODE: if ( PL_endav ) { long i ; SV **svp = av_fetch(PL_endav , 0 , FALSE) ; long lng = av_len( PL_endav ) ; EXTEND(SP, lng + 1 ) ; for( i = 0 ; i <= lng ; ++i ) { cv_end = (CV *) svp[i] ; if ( !strcmp( HvNAME(CvSTASH(cv_end)) , pkg) ) { PUSHs( newRV_inc( cv_end ) ); } } }
    And you can use in this way:
    my @end_subs = get_end_sub( 'Package::Foo' ) ; my $sub = $end_subs[0] ; &$sub() ;

    Graciliano M. P.
    "Creativity is the expression of the liberty".

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://355166]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (7)
As of 2014-08-23 18:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (178 votes), past polls