perl - 在Perl中,重新加载模块和重新定义子程序

  显示原文与译文双语对照的内容

我目前正在尝试重新加载一个模块。 我希望实现的目的是能够在模块文件中更改定义的子例程中的某些内容,然后使用新的定义。

目前,在等待子例程执行原始代码之前,我正在更改 test 子例程中的print语句。

但是,我目前得到的是消息:
Subroutine test redefined at/Test/testmodule.pm line 9.

这正是我想要的,但是输出如下。

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

我希望在重新加载模块时,重新定义子例程,即下次执行测试子例程,而不是旧的。

我已经搜索过关于重载模块的问题,但给出的答案是循环依赖( 包A 使用了B,而B 使用了),或者在包中冲突。 我需要子例程重定义,并且使用了新的定义。

源代码: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 ( 相对于 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 textn"); # this line is edited in the source file to


 # 'print("this is some different textn");'


}


1;



对教程的任何指针或者参考都是。 事实上,如果答案不是很简单,不要直接告诉我答案,让我看看你建议的材料。

所有必需的CPAN模块都已经安装,我可以确认在更改后,成功地编写了 testmodule.pm 。

:科学 Linux 6,内核版本 2.6.32 -131.4. 1. el6.x86_64
为x86_64-linux-thread-multi构建了 ( * ): v5.10.1

很感谢你的帮助
欧文。

时间: 原作者:

我不知道这是否是问题,但是你在模块中丢失了 package 语句。 这意味着 testmain::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 1n";


}



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不会创建命名空间。 当你说 package NamespaceName 或者引用这个名称空间时它就创建了一个名称空间


sub Test::testmodule::test {


 print"this is some text, counter 1n";


}



由于版本中的test 函数不在 Test::testmodule 命名空间中,所以它没有被重新加载。

原作者:
...