tags:

views:

81

answers:

2

As the title says, I'm not clear on when such a subroutine will be called. From the require page at perldoc one can write:

push @INC, \&my_sub;
sub my_sub {
   my ($coderef, $filename) = @_; # $coderef is \&my_sub
   ...
}

but where does this go exactly? The required package or the requiring script (or package)? I've tried both with some sentinel print statements but neither worked so clearly there is something I'm not getting.

+8  A: 

Perl calls a subroutine reference in @INC when it is traversing @INC to look for a module. That is, you'll trigger it when you try to load a module with use or require and Perl does not find that module in the preceding @INC locations.

BEGIN {
    push @INC, 
      sub { print "Oops: There was an error looking for $_[1]\n"; };
    }

eval "use Cat::Burglar";
eval "use Local::NotThere";
require Cat::Burglar;

You need to ensure that your subroutine reference is in @INC before you try to load the modules. Remember that use is a compile time feature and that require is a run time feature. As with adding other "regular" @INC entries, you probably want to do it in a BEGIN block as early as possible in your program.

brian d foy
Wow, somehow I've read the `require()` docs many times without noticing this feature!
Ether
And that's why we have brian who knows the docs by heart! :) Cool feature, thanks to OP and brian for introducing it! +1 for both
DVK
I don't know the docs by heart. I just know how to google.
brian d foy
@brian - Don't ruin the magic for us!!! next thing you'll say that automagical features don't work by magic! :(
DVK
Huh? Is that comment just a jokey banter or does it actually connect to something in my answer?
brian d foy
+1  A: 

To avoid confusing our subroutine with the subroutines in the standard Perl modules generally it is good to use the unshift instead of push. So it will first use your subroutine from the @INC.

I think that should read something like "To *prefer* our sub routine with the loading modules the standard perl modules"
justintime
Yeah! You are correct justintime. Sorry for my English
Which array operation you use depends on what you are doing and when you want to the code reference to trigger. unshift puts it at the front of the array, push at the end, and splice will put it in any position you like. It's task-dependent though.
brian d foy