我正在尝试重新加载模块.我希望实现的目标是能够在模块文件中的已定义子例程中更改某些内容,然后使用新定义重新加载该模块.
目前,我正在更改测试子程序中的print语句,在等待子程序执行原始代码之后,以及在重新加载模块之前,打印“这是一些不同的文本”.
但是,我目前得到的是消息:
子程序测试在/Test/testmodule.pm第9行重新定义.
这正是我想要的,但输出如下.
this is some text Subroutine test redefined at /Test/testmodule.pm line 9. this is some text
我希望的是,当模块重新加载,并且它意识到子程序已被重新定义时,下次执行测试子程序时,它将引用新定义而不是旧定义.
我已经搜索了以前关于重新加载模块的问题,但给出的答案是循环依赖项(包A使用B,B使用A)或包中的命名空间冲突,但这不是手头的问题.我希望重新定义子例程,并使用新的定义.
源代码:
main.pl
#!/usr/bin/perl use strict; use warnings; use Module::Reload::Selective; use Test::testmodule; while(1) { test(); #run module's 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! }
源代码:testmodule.pm(在./Test/中相对于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;
任何指针或对教程的引用都会很棒.事实上,如果答案不是非常简单,不直接告诉我答案将允许我阅读您建议的材料,并获得整体更好的理解.
已安装所有必需的CPAN模块,我可以确认更改后成功写入了testmodule.pm.
OS: Scientific Linux CERN 6,kernel version 2.6.32-131.4.1.el6.x86_64
Perl: v5.10.1 (*) built for x86_64-linux-thread-multi
提前谢谢了,
欧文.
解决方法
我不知道这是不是问题,但你错过了模块中的包语句.这意味着test是main :: test而不是Test :: testmodule :: test.
是的,这是cjm的答案与我的结合.这段代码适合我:
在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;
在main.pl中:
#!/usr/bin/perl use strict; use warnings; use Module::Reload::Selective; use Test::testmodule; while(1) { test(); #run module's 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; }
为了澄清,Perl 5在创建.pm文件时不会创建命名空间.当你说包NamespaceName或你像这样引用那个命名空间时,它会创建一个命名空间
sub Test::testmodule::test { print "this is some text,counter 1\n"; }
由于您的版本中的测试函数不在Test :: testmodule命名空间中,因此它从未重新加载.