Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: INIT blocks and runtime code loading

by broquaint (Abbot)
on Apr 26, 2004 at 23:55 UTC ( [id://348366]=note: print w/replies, xml ) Need Help??


in reply to INIT blocks and runtime code loading

Assuming a relatively recent version of perl (5.7.1+ IIRC) you can execute INIT at your discretion. However the trick is in avoiding executing them twice. Here's a very bare bones example of executing INIT blocks from both use and require
package testpkg; BEGIN { warn "in BEGIN\n" } { no warnings; INIT { return if $INIT_DONE++; warn "in INIT\n"; } } { use B; $_->object_2svref->() for grep { $_->GV->STASH->NAME eq __PACKAGE__ } B::init_av->ARRAY; } 1;
And some usage code
$ perl -we 'use testpkg;' in BEGIN in INIT $ perl -we 'require testpkg;' in BEGIN in INIT
Unfortunately it uses a rather horrific bodge of a package variable and post-increment behaviour, but nonetheless, it works :) Hopefully there's some very straight-forward solution for determining what state perl is in when a piece of code is executing, but currently I'm out of ideas.
HTH

_________
broquaint

Replies are listed 'Best First'.
Re^2: INIT blocks and runtime code loading
by jdhedden (Deacon) on Jun 24, 2005 at 14:10 UTC
    One wrinkle on broquaint's kludge is its interaction with an import subroutine.
    'use'ing a module normally goes through:
    BEGIN
    import
    INIT
    
    However, adding an import subroutine to the above code produces:
    BEGIN
    INIT
    import
    
    One possible workaround for this would be to move any INIT code to the end of the import subroutine. Yet even this is not a 100% solution as:
    use testpkg ();
    causes the import subroutine - and hence the moved INIT code - not be be executed.

    For the module I'm writing, I have a BEGIN block, an import subroutine, and an INIT block. The INIT block consists of just one function call. Therefore, I warn the user that if they want delayed evaluation of my module, they must do so as follow:

    eval { require MyModule; import MyModule qw/.../; MyModule::MyInit(); }

    Remember: There's always one more bug.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2024-04-26 01:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found