Reload modules and redefine routines in Perl

I'm currently experimenting with rebooting the module. The goal that I hope to achieve is the ability to change something in a specific routine in a module file, and then reload this module using new definitions.

I am currently modifying the print statement in the test routine to print β€œthis is some other text” after waiting for the source routine to execute and before the module is reloaded.

However, what I am currently receiving is this message:
Subroutine test redefined at /Test/testmodule.pm line 9.

This is exactly what I want, but the conclusion is as follows.

  this is some text
 Subroutine test redefined at /Test/testmodule.pm line 9.
 this is some text

I hope that when the module is reloaded and it understands that the subroutine has been redefined, the next time that it runs the test subroutine, it will refer to the new definition, not the old one.

I looked through previous questions about reloading modules, but the answers were like loop hangs (package A uses B and B uses A) or namespace conflicts in packages, but this is not a problem, I want to redefine the subroutine and use the new definition.

source code: main.pl

 #!/usr/bin/perl use strict; use warnings; use Module::Reload::Selective; use Test::testmodule; while(1) { test(); #run module define subroutine sleep(5); #stop terminal from being flooded too quickly #Ensure that the module is reloaded $Module::Reload::Selective::Options->{SearchProgramDir} = 1; $Module::Reload::Selective::Options->{ReloadOnlyIfEnvVarsSet} = 0; Module::Reload::Selective->reload(qw(Test::testmodule)); #reload! } 

source code: testmodule.pm (in ./Test/ relative to main.pl)

 #!/usr/bin/perl use strict; use warnings; # allow exportation require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(test); sub test { print("this is some text\n"); # this line is edited in the source file to # 'print("this is some different text\n");' } 1; 

Any pointers or links to textbooks would be brilliant. In fact, if the answer is not incredibly simple without telling me that the answer will directly allow me to read your proposed material and gain a general understanding.

All the necessary CPAN modules have been installed, and I can confirm that testmodule.pm is successfully written after the change.

OS : Scientific Linux CERN 6, kernel version 2.6.32-131.4.1.el6.x86_64
Perl : v5.10.1 (*) for x86_64-linux-thread-multi

Thank you very much in advance,
Owen.

+4
source share
3 answers

I don't know if this is a problem or not, but you are missing your package statement in the module. This means that test is main::test not Test::testmodule::test .

Yes, it was a combination of cjm and mine answer. This code works for me:

In Test/testmodule.pm :

 package Test::testmodule; use strict; use warnings; # allow exportation require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(test); sub test { print "this is some text, counter 1\n"; } 1; 

In main.pl :

 #!/usr/bin/perl use strict; use warnings; use Module::Reload::Selective; use Test::testmodule; while(1) { test(); #run module define subroutine my $module = do { open my $fh, "<", "Test/testmodule.pm" or die "could not open the module: $!"; local $/; <$fh>; }; $module =~ s/counter ([0-9])/"counter " . ($1 + 1)/e; open my $fh, ">", "Test/testmodule.pm" or die "could not open the module: $!"; print $fh $module; close $fh; #Ensure that the module is reloaded $Module::Reload::Selective::Options->{SearchProgramDir} = 1; $Module::Reload::Selective::Options->{ReloadOnlyIfEnvVarsSet} = 0; Module::Reload::Selective->reload(qw(Test::testmodule)); Test::testmodule->import; } continue { sleep 1; } 

To clarify, Perl 5 does not create a namespace when creating a .pm file. It creates a namespace when you say package NamespaceName , or reference this namespace like this

 sub Test::testmodule::test { print "this is some text, counter 1\n"; } 

Since the test function in your version was not in the Test::testmodule , it never reloaded.

+4
source

You missed the module :: Reload :: Selective docs part, which says, to invoke import after the reboot. (Although it uses indirect object syntax, it is better to use a standard method call.) That is, you should have said:

 Module::Reload::Selective->reload(qw(Test::testmodule)); #reload! Test::testmodule->import; #reimport! 

The reason is that Exporter is essentially:

 *main::test = \&Test::testmodule::test; 

That is, main::test is assigned a link to the current version of Test::testmodule::test . Rebooting the module overrides Test::testmodule::test , but main::test continues to reference the original sub. Invoking the import method explicitly copies the new version of sub to main::test .

+3
source

You can stop the issued warning by setting

 no warnings 'redefine'; 

into the loaded module.

Also note that reloading is a rather fragile concept, and this may limit what you can do in your modules.

+2
source

All Articles