£okì has asked for the wisdom of the Perl Monks concerning the following question:

Ok, now this baffles me to the core. I'm very simply using a subroutine:
sub reload_module { undefSub("on_public"); delete $INC{"contrib.pl"}; require "contrib.pl"; }
to reload a module when using POE::Component::IRC. The on_public subroutine is the only sub (the only anything now) in the module contrib.pl (for testing). When I run the reloader, nothing reloads. However, here's when it gets funny. If I just write a testing script that does the same reload but not using POE, it works. Now, here are the two places I THINK there could be a problem. 1:
POE::Session->new ( _start => \&bot_start, irc_001 => \&on_connect, irc_public => \&on_public, irc_notice => \&on_notice, irc_msg => \&on_msg, );
Could it be that when you use this type of session that it caches the subroutine? If so, how to I force this session to refresh without reconnecting? 2: In the on_public subroutine, it basically just outputs this
$_[KERNEL]->post( $irc{server} => privmsg => $irc{chan}, "\0037 this i +s the standard test!");
Could it be caching that?? Anyone know? I'd bet it's #1 but I don't know how to go about clearing out that session info.

Replies are listed 'Best First'.
Re: Caching of Subroutines
by revdiablo (Prior) on Jan 03, 2005 at 18:30 UTC
    Could it be that when you use this type of session that it caches the subroutine?

    No, that merely creates references to the subroutines. You can update the subroutine at runtime, and as long as the reference points to the right thing, it will be fine. [If there's a way to do this, I don't know it. Everything I've tried creates a new coderef, which means any old references point to the old sub.]

    Your problem is that when you undefine the sub, you are breaking the reference you previously created. A workaround to this could be:

    POE::Session->new ( _start => \&bot_start, irc_001 => \&on_connect, irc_public => sub { on_public(@_) }, irc_notice => \&on_notice, irc_msg => \&on_msg, );

    Update: fixed a few errors.

    Another update: simonm's method may be preferable, as it uses the &subroutine calling variety to pass @_ implicitly. Another way would be goto &subroutine which replaces the current entry in the call stack.

      Nice solution. Can't use my globals anymore obviously but that can be worked around.
Re: Caching of Subroutines
by simonm (Vicar) on Jan 03, 2005 at 18:43 UTC
    The irc_public => \&on_public reference continues to point to the original subroutine even after the package that contained it is reloaded. (This is what lets you wrap subroutines by saying my $old = \&subname; *subname = sub { &$old }.)

    As revdiablo suggests, pass a code reference that explicitly calls the subroutine by name so that the new definition will be found: irc_public => sub { &MyPackage::subname }.