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

Re^2: eval "require $class" seems wrong

by rvosa (Curate)
on Aug 22, 2007 at 17:48 UTC ( #634450=note: print w/replies, xml ) Need Help??

in reply to Re: eval "require $class" seems wrong
in thread eval "require $class" seems wrong

It looks like what UNIVERSAL::require does is: turn $class name (e.g. Some::Class) into a path (Some/, then do eval qq{require $path}, which amounts to the same thing - a string eval - but hidden in a dependency. Okay, it checks %INC first to see if it's already been loaded, but that's about it.

Replies are listed 'Best First'.
Re^3: eval "require $class" seems wrong (--!$@)
by tye (Sage) on Aug 22, 2007 at 19:05 UTC

    If you change "::" to "/" and append ".pm", then you don't need a string eval, you can just do require $class. I wouldn't even do eval { require $class } (non-string eval) unless I was wanting to work around the module not being found. But if you do want to eval, then the best choice is:

    ( my $file= $class ) =~ s-::|'-/-g; if( ! eval { require "$"; 1 } ) { # work-around the failure here }

    But I don't find the argument against string eval compelling enough to have much of a strong preference between that and the below string eval unless there is risk that $class might contain mischevious data:

    if( ! eval "require $class; 1" ) { # work-around the failure here }

    If you don't want to work-around a failure (and trust $class), then the choices are:

    eval "require $class; 1" or die $@;


    ( my $file= $class ) =~ s-::|'-/-g; require "$";

    And I'd never use UNIVERSAL::require, since I consider poluting such a very global namespace to be way too much sin for the sake of saving one line of code.

    - tye        

      The 1 is useless since require always returns true. (If it encounters no error, it returns what the module returns. If the module returns false, it encountered an error. If it encounters an error, it throws an exception.)

        Yes, and the space is equally "useless" because require"$" works just fine. That doesn't mean I'm going to drop either of them.

        The "; 1" is part of the best practice. It may not change the effect of this particular code, but it means I don't have to worry about whether the preceeding code might return a false value rather than dieing. It also tells the reader that I'm testing whether eval succeeded not whether the eval'd code returned a true value (which also makes it clearer why I'm using eval at all).

        - tye        

Re^3: eval "require $class" seems wrong
by ikegami (Pope) on Aug 22, 2007 at 19:20 UTC

    It uses eval EXPR for #line to work. It has nothing to do with require. (eval BLOCK would suffice if you wanted to catch exceptions.)

    The following will work (even if your platform doesn't use / as the path seperator):

    $class = 'HTTP/'; require $class;

    However, transforming the class name into a path is really no better.

Re^3: eval "require $class" seems wrong
by lima1 (Curate) on Aug 22, 2007 at 18:22 UTC
    Sure, you need an eval here to check whether the module was found and successfully loaded. You need the eval in the first case to interpolate the module name and turn it into a bareword, or not?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://634450]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2017-03-30 19:53 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (363 votes). Check out past polls.