The wrapping works as I wrote it--there will be no circular fatal recursion. In order to understand why one must understand how typeglobs work. \&foo is copying *foo{CODE} which is the code slot for the foo symbol. *foo = sub { ... } on the other hand assigns a new value to *foo{CODE}, given that the subroutine foo was defined already.

My first approach to do what you want would be to simply require IWL::Script right away instead of putting a hook in @INC, and then you can safely wrap the subroutine. Once the module is loaded it won't reload upon a new require (unless someone has fiddled with %INC).

A big problem with your technique is that someone somewhere might unshift elements into @INC and therefore your hook may miss to wrap the subroutine. I'm not sure if tieing @INC is supported, but that could be a solution. However, if someone else ties @INC your tie will be superceeded, and again you miss to wrap the subroutine. Or if someone else already has tied @INC you'll have trouble too.

I really recommend you to just load the module straight away. If you for some reason want to delay the loading of the module you need to do two things, one of which you've already solved:

The second point is done by returning a code ref. (perldoc -f require has all the details about that.) Here's an example:
use strict; require lib; lib::->import( sub { my ($self, $filename) = @_; lib::->unimport($self); # Enable require below. require Benchmark; # Some module that exists, just as demo. lib::->import($self); # Put it back in business. my $rc = 1; return sub { $_ = 1 if $rc; return $rc--; }; } ); print "Trying to require some modules that doesn't exist, "; require This::Does::Not::Exist; require Cwd; require This::Does::Not::Exist::Either; print "and it worked.\n"; __END__ Trying to require some modules that doesn't exist, and it worked.
The code reference returned by the hook first sets $_ to a true value that is taken as the source code for the module that's required, and returns 1 to signal success. Then it returns 0 to signal EOF.

Applying this to your case, you change require Benchmark; to require $filename; in the hook, and after that you wrap the subroutine.

Now you hopefully have the bits and pieces to make this work the way you want it to work.

lodin


In reply to Re^3: Notification on module load, and redefinition of module methods. by lodin
in thread Notification on module load, and redefinition of module methods. by /dev/urandom

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.