Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
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 imbibing at the Monastery: (7)
As of 2015-07-04 09:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (59 votes), past polls