Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Re: Reloading modules- suppressing warnings works sometimes?

by !1 (Hermit)
on Dec 21, 2003 at 01:27 UTC ( #316120=note: print w/replies, xml ) Need Help??

in reply to Reloading modules- suppressing warnings works sometimes?


package reload; use strict; use warnings; sub reload { my ($PM) = @_ or return; $PM =~ s!::!/!g; $PM .= ".pm"; delete $INC{$PM}; no strict 'refs'; no warnings 'redefine'; my $warnings = \&warnings::import; local *warnings::import = sub { &{$warnings}; unimport warnings "redefine"; }; eval { require $PM }; } 1;

It should still work as before except it won't spew out redefine errors.

Replies are listed 'Best First'.
Re: Re: Reloading modules- suppressing warnings works sometimes?
by JPaul (Hermit) on Dec 21, 2003 at 20:07 UTC

    I have to admit - I don't fully understand entirely what the above does - I've only got a vague idea - but it works perfectly :)

    Well done :)

    -- Alexander Widdlemouse undid his bellybutton and his bum dropped off --

      In a nutshell:

      sub reload { my ($PM) = @_ or return; $PM =~ s!::!/!g; $PM .= ".pm"; delete $INC{$PM};

      We return unless we get something to load. After that, we convert all ::'s to / and append .pm to the end of our module name because that's how it's stored in %INC and it keeps us from needing to eval string.

      no strict 'refs'; no warnings 'redefine';

      Just what it says.

      my $warnings = \&warnings::import; local *warnings::import = sub { &{$warnings}; unimport warnings "redefine"; };

      Ok. The magic happens here. $warnings contains a coderef to the warnings import method. It's very important that we keep this since may change between versions and we'd very much enjoy this not breaking just because we have a new warnings module. Anywho, the next line localizes the warnings::import typeglob. To this, we assign a subroutine that first calls our old warnings::import method with all the same parameters. Notice that I call it as &{$warnings} instead of $warnings->(). I could have done $warnings->(@_) as well, but what fun is that? Anyhow, since we imported whatever the calling script/module wanted we need to unimport the redefine warning immediately afterwards. Remember that this gets called from the module in question whenever it uses warnings. Thus it will affect the $^WARNING_BITS variable at that point.

      eval { require $PM }; }

      I love eval braces. Of course, it's used here because if require can't find the module it will kill the script. Just check the return from reload::reload to make certain the module did in fact load. Also of note is that at the end of the subroutine, warnings::import is magically restored to its old import method.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (4)
As of 2021-09-19 11:19 GMT
Find Nodes?
    Voting Booth?

    No recent polls found