如何在perl中堆栈函数定义(同时调用它们)?

goqiplq2  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(203)

所以我想要这样的东西:
module0.pl

sub fun {
    print "fun $_[0] from 0\n"
}

1

module1.pl

sub fun {
    print "fun $_[0] from 1\n"
}

1

main.pl

BEGIN{push @INC, "."};

require "module0.pl";
require "module1.pl";

fun("test")

将打印(以任何顺序-我不在乎):

fun test from 0
fun test from 1

这是可能的吗?最优雅的语法是什么?

bjp0bcyl

bjp0bcyl1#

所以你想从不同的包中调用一个subs的列表(这里同样命名)?
单向,使用普通包

package Pack1;

use warnings;
use strict;
use feature 'say';

sub fun { say "fun $_[0] from ", __PACKAGE__ }

1;

调用程序,与此软件包(及其副本Pack2)位于同一目录中

use warnings;
use strict;
use feature 'say';

use FindBin qw($RealBin);
use lib $RealBin;

use Pack1;
use Pack2;

for my $packname (qw(Pack1 Pack2)) { 
    MAKENAME: {
        no strict 'refs';
        my $fun_name = $packname . '::' . 'fun';
        $fun_name->("hi") if exists &{$fun_name};
    }   
}

我将作用域化no strict 'refs'放在另一个块中,并将该块命名为no strict 'refs';如果这就是循环中所做的一切,那么就不需要引入另一个作用域。†我们需要关闭refs限制,以便将其用作子例程引用,但这样也可以对名称本身进行作用域。
几点注意事项

  • 我不知道为什么那些是.pl文件,而它们是require-艾德;它们应该是包,我是这样写的。让我知道是否有一个具体的(和无与伦比的)原因让它们成为require-艾德程序
  • 使用lib pragma$FindBin::RealBin@INC添加目录,而不是通过黑客攻击@INC

†或复制代码ref

for my $packname (qw(Pack1 Pack2)) {
    my $fun = \&{ $packname . '::' . 'fun' };

    $fun->('hi');
}

但如果我们真的需要检查它的存在性

for my $packname (qw(Pack1 Pack2)) {

    my $fun_name = $packname . '::' . 'fun';
    next if not exists &{$fun_name};

    my $fun = \&{$fun_name};

    $fun->('hi');
}
nlejzf6q

nlejzf6q2#

一种相当可靠的方法是使用注册表进行回调。
第一个

相关问题