加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

重新加载模块并重新定义Perl中的子例程

发布时间:2020-12-15 23:21:58 所属栏目:大数据 来源:网络整理
导读:我正在尝试重新加载模块.我希望实现的目标是能够在模块文件中的已定义子例程中更改某些内容,然后使用新定义重新加载该模块. 目前,我正在更改测试子程序中的print语句,在等待子程序执行原始代码之后,以及在重新加载模块之前,打
我正在尝试重新加载模块.我希望实现的目标是能够在模块文件中的已定义子例程中更改某些内容,然后使用新定义重新加载该模块.

目前,我正在更改测试子程序中的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 textn"); # this line is edited in the source file to
                                  # 'print("this is some different textn");'
}
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 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 5在创建.pm文件时不会创建命名空间.当你说包NamespaceName或你像这样引用那个命名空间时,它会创建一个命名空间

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

由于您的版本中的测试函数不在Test :: testmodule命名空间中,因此它从未重新加载.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读