Diddling @INC, order of entries in it
Adriano Ferreira
a.r.ferreira at gmail.com
Wed Aug 1 18:48:21 BST 2007
On 8/1/07, David Cantrell <david at cantrell.org.uk> wrote:
> [ Adriano Ferreira CCed so he knows just what kind of insanity I'm
> inflicting on his code :-) ]
>
> I'm hacking around in the guts of Devel::Hide, trying to add a facility
> to make it hide modules from child processes created by fork-and-exec,
> so eg ...
>
> use Devel::Hide qw(-fromchildren Foo::Bar);
>
> system("perl -MFoo::Bar ..."); # Foo::Bar is unavailable here
>
> D::H works by putting a coderef into @INC, which checks what you're
> trying to load, and which fails as appropriate.
>
> I have it so that if you pass the magic value '-fromchildren' to D::H's
> import() like above, it puts MDevel::Hide=Foo::Bar into PERL5OPT. And it
> works.
>
> It works right up until the child process does this ...
>
> use lib 'my/secret/stash/of/modules';
> use Foo::Bar;
>
> cos then, 'my/secret/stash/of/modules' gets stuffed into @INC *before*
> the coderef, and so if Foo::Bar can be found under there, it gets
> loaded. I don't want this to happen, partly because it makes writing
> the tests (which start with 'use lib "t"') for the new bits of code in
> Devel::Hide a bit annoying.
> Can anyone think of a nifty way around this? The only one I can think
> of is to have Devel::Hide mess around in the guts of lib.pm and change
> them so that the reference to Devel::Hide's magic subroutine *always*
> comes first.
Once you start playing tricks with "lib", you will be surprised by
code that does not use "lib" but "@INC" directly, doing only:
BEGIN { push @INC, 'my/private/lib/dir' }
So messing with "lib" would not be enough. I think that playing with a
tied @INC won't work either, if someone do
BEGIN { @INC = ( 'my/private/lib/dir', @INC ) }
or even worst things.
> If I *do* have to mess around in lib's guts, I imagine what I want to
> do is replace its import() with one that goes ...
>
> sub import {
> # call the original import(), save its return value
> search @INC and move my magic subroutine to the beginning
> # return the original import()'s return value
> }
>
> And indeed *should* I be trying to subvert 'use lib' like this? I can
> make the tests pass by putting Mlib=t in the right place in PERL5OPT, of
> course, so perhaps that's the better choice.
On 8/1/07, Dan Rowles <d.rowles at outcometechnologies.com> wrote:
> How about you override the require method? Or possibly the "do" method
> instead?
>
> Dan
I think that may be the way to go. I didn't have thought before of
overriding "do". Can it be done?
Regards,
Adriano.
> --
> David Cantrell | Reality Engineer, Ministry of Information
>
> I hate baby seals. They get asked to all the best clubs.
>
More information about the london.pm
mailing list