Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

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

by holli (Monsignor)
on Jan 11, 2005 at 17:58 UTC ( #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.

Comment on Evaled::INIT - allow init blocks to execute inside eval block
Select or Download Code
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
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? | Other CB clients
Other Users?
Others chanting in the Monastery: (10)
As of 2016-05-30 08:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?