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

Re: Overriding the built-in require function (@INC)

by tye (Sage)
on Feb 04, 2008 at 21:09 UTC ( [id://666107]=note: print w/replies, xml ) Need Help??


in reply to Overriding the built-in require function

You can also push a code ref (that returns undef) onto the front of @INC:

BEGIN { unshift @INC, sub { my( $self, $file )= @_; print "Searching for $file...\n"; return; }; } require Net::Ping;

See require for more details and other options.

- tye        

Replies are listed 'Best First'.
Re^2: Overriding the built-in require function (@INC)
by /dev/urandom (Beadle) on Feb 04, 2008 at 21:51 UTC
    That would not serve my purposes, as any modules in question will not yet be loaded when the subref receives it.
      That's precisely the point: @INC is the list of paths that perl will search when it goes to load your module. If you put a code ref into @INC, perl will recognize it and execute it (rather than treating it as a path to search). By pushing your sub onto the front of @INC, you'll ensure that perl checks it first. By returning undef, you'll cause perl to keep looking until it finds the real path.

      The very end of the doc that tye linked, require, describes this in detail. The same @INC method works for use.

        I think the OP's example is misleading you somewhat. When /dev/urandom says "That would not serve my purposes, as any modules in question will not yet be loaded when the subref receives it." I take that to mean that what /dev/urandom will do with the repurposed require function is to actually manipulate the module the instant it gets loaded, before anyone else can do anything with it. The original post said that it illustrated the issue, but not the why of it. Perhaps a better illustration would be:

        *CORE::GLOBAL::require = sub { CORE::require($_[0]); if ($_[0] eq 'Net/Ping.pm') { $Net::Ping::TIMEOUT = 5000; # milliseconds } };
        I believe the OP means that they want to do something like that (I don't think that the code there would work even if everything else works - I don't think Net::Ping has a $TIMEOUT available). Perhaps check the $VERSION, or whatever. Modifying the @INC to include a code ref wouldn't allow for this - you merely return the code (via a filehandle), but at this point, it hasn't been compiled, so you can't interact with it yet.

        I suspect it'd be better to derive from Net::Ping, and change the code to require that module instead... but we really don't have enough details to be definitive about this.

Re^2: Overriding the built-in require function (@INC)
by lodin (Hermit) on Feb 06, 2008 at 22:53 UTC

    But this of course fails if someone happens to do

    BEGIN { unshift @INC, sub { ... } } use lib 'somewhere/special'; require Net::Ping; # Resolves to "somewhere/special/Net/Ping.pm".
    as lib also unshifts @INC. This accident may not be obvious if it's a module that uses lib.

    For many purposes it works, but one should be aware of that it's not bullet proof against accidents.

    lodin

Log In?
Username:
Password:

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

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

    No recent polls found