Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Interesting behavior in eval block

by ikegami (Patriarch)
on Jun 19, 2008 at 18:33 UTC ( [id://692987]=note: print w/replies, xml ) Need Help??


in reply to Interesting behavior in eval block

Outside a situation that expects a bareword (such as the LHS of => and print's first argument), a bareword is compiled into a function call only if a function by that name exists at that time. Otherwise, it is compiled as a string constant (strict off) or results in an error (strict on).

use executes as soon as it compiles, so the function it imports are present before the rest of the file is compiled. However, you deferred the execution of use to when the eval is executed, which is only after the entire file (including what you want to be a call to gettimeofday) has been compiled.

Remember that use Module; is the same as BEGIN { require Module; import Module; }, so the solution is to reintroduce BEGIN. Put a BEGIN block around the while and you'll get the desired behaviour. The loop will execute as soon as it finishes compiling, which is before the compiler reaches "gettimeofday".

Update: Reorganized text to improve readability.

Replies are listed 'Best First'.
Re^2: Interesting behavior in eval block
by l2kashe (Deacon) on Jun 19, 2008 at 18:45 UTC
    That makes sense, but this is a contrived minimal example of the implementation. This will be run well after compile time off of config data, or object instantiation values. So the questions is can I somehow muck with the symbol table to get where I want to be? Maybe something like
    while ( my($module, $args) = each %$toLoad ) { my $str = "use $module "; # to fix typo in example $str .= 'qw(' . $args . ')' if $args ne '1'; eval $str; # Try and remap symbol tables to the right spot unless ( $args eq '1' ) { no strict 'refs'; foreach my $key ( split/\s+/, $args ) { *$key = *$module::$key; } } # END unless args eq 1 } # END while each toLoad

    This would cover the standard cases but fail for things like use CGI qw(:all); and similar megaKeywords

    I imagine this is a standard pattern, I just don't know where to look for the docs to get at what I want without potentially digging into other modules EXPORT_* variables, which doesn't seem right either

    use perl;
    Everyone should spend some time pounding nails with their forehead for a while before they graduate to complicated stuff like hammers. - Dominus

      Your "trick" doesn't work. You're just duplicating the work the implicit import in use already does. Like I said in my original post, it's *when* it happens that's important.

      You have the right idea, but it needs to be done at compile-time. Fortunately, it's very simple since Perl already provides a means of declaring a function that's to be defined at a later time.

      sub gettimeofday(); # Eventually. eval "use Time::HiRes qw( gettimeofday ); 1" or die "Unable to load Time::HiRes: $@\n"; print(gettimeofday);

      The parens in "sub gettimeofday();" are only there because Time::HiRes declares the function using that prototype.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (3)
As of 2024-04-20 01:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found