Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Evaled::INIT - allow init blocks to execute inside eval block

by holli (Abbot)
on Jan 11, 2005 at 17:58 UTC ( [id://421351]=perlmeditation: print w/replies, xml ) Need Help??

Brothers in perl,
here is a little module that i like to discuss. It is a workaround to the issue that INIT-Blocks are not executed in an evaled environment like mod_perl and WSH (Windows Scripting Host). Everything else you need to know is in the pod.
Do you thinks itīs well written? do you detect any caveats? what about the name?

eager to hear the monks wisdom,
holli
package Evaled::INIT; use 5.008; use strict; use warnings; our $VERSION = '0.01'; my $filter; use Filter::Simple sub { return if $filter++; my $i=0; while ( $_ =~ s/(^|[\s\t;}])INIT(?!\x00)([\s\n]*|{)/$1INIT\x00 { \ +&SINIT$i; } \nsub SINIT$i$2/ms ) {$i++;}; s/\x00//msg; }; 1; __END__ =head1 NAME Evaled::INIT - Perl extension for executing INIT-sections =head1 SYNOPSIS use Evaled::INIT; =head1 ABSTRACT When you I<use> a module in an I<eval()>-statement, then the modules I<INIT>-sections (if any) are not executed. This modu +le can be used to work-around this behaviour. =head2 VERSION This is Version 0.1, early beta-state ,-) =head1 DESCRIPTION When you I<use> a module in an I<eval()>-statement, like $mod = "Foo"; eval "use $mod;"; then the modules I<INIT>-sections (if any) are not executed. Such statements may be used to load unknown modules at runtime, or might be implicitly caused by an environment like the I<Windows Scr +ipting Host (WSH)> or mod_perl. Such a WSH-PerlSript is always executed within an I<eval()>. This behaviour can cause the module to act irregularly. If you need to use such a module in any I<eval>-statement you can you +use this module to work around. Simply add the line use Evaled::INIT; at the top of the modules code (right after the I<package xxx;>-statem +ent). I<Evaled::INIT> acts as a source-filter. B<Hint:> I<A source-filter is a module that can change the sourcecode of the mo +dule that uses it to whatever the filter wants. This happens before the modules code is com +piled.> In this case the filter will replace all INIT { #do something } with INIT { &SINITx(); } sub SINITx { #do something } where I<x> is the number of the I<BEGIN>-section (there can be more th +an one) in top-down-order, starting with 0. After that conversion you can call the I<SINITx>-Functions as apropria +te, like $mod = "Foo"; eval "use $mod;"; eval "&$mod::SINITx();"; =head2 EXPORT None by default or query. =head2 EXAMPLES =head3 Bad example, INIT is not executed. #File t.pm INIT { print "INIT\n"; } 1; #File t.pl eval "use t.pm;"; print "main\n"; Output: >>perl t.pl main >> =head3 Good example, INIT can be called. #File t.pm use Evaled::INIT; INIT { print "INIT\n"; } 1; #File t.pl eval "use t.pm; &t::SINIT0();"; print "main\n"; Output: >>perl t.pl INIT main >> =head3 Good example, INIT still works #of course the module will still work without eval #File t.pm use Evaled::INIT; INIT { print "INIT\n"; } 1; #File t.pl use t.pm; print "main\n"; Output: >>perl t.pl INIT main >> =head1 AUTHOR Markus Holzer (m.holzer/at/kvsaarland.de) =head1 COPYRIGHT AND LICENSE This library is free software; you can redistribute it and/or modify i +t under the same terms as Perl itself. =cut

Retitled by davido.

Replies are listed 'Best First'.
Re: Evaled::INIT - allow init blocks to execute inside eval block
by Juerd (Abbot) on Jan 11, 2005 at 18:48 UTC

    You should probably mention that this works only for INIT blocks, not for everything that does its thing during INIT. For example, attributes.

    Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

      Agreed. I did not read about Attributes yet, nor did i know that they exist. So i will do some rtfm.
Re: Evaled::INIT - allow init blocks to execute inside eval block
by dragonchild (Archbishop) on Jan 11, 2005 at 18:06 UTC
    That is very cool ...

    Question - why do you need "use 5.008;"? From what I'm seeing, that should work clear back to at least 5.004 ... or am I missing something?

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      I believe INIT blocks were only introduced in 5.005. :)
Re: Evaled::INIT - allow init blocks to execute inside eval block
by PodMaster (Abbot) on Jan 12, 2005 at 07:42 UTC
    I think the first thing you should reveal about this module is that it is a filter. It should probably have the word Filter in its name.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      like Evaled::InitFilter?
        I was thinking more like Filter::PreserveINIT or Filter::INIT2SUB.

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (3)
As of 2024-03-19 03:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found