perl中的分派函数,如何包含我们的列表
我发现在perl中分派许多函数的最快方法是使用函数引用。 剩下的问题是,我必须在分派器和函数模块中的($func1,$func2,…)列表中包含函数名。我无法找到任何方法来包含它们,就像C include那样。这是我的代码: 主要模块:perl中的分派函数,如何包含我们的列表,perl,Perl,我发现在perl中分派许多函数的最快方法是使用函数引用。 剩下的问题是,我必须在分派器和函数模块中的($func1,$func2,…)列表中包含函数名。我无法找到任何方法来包含它们,就像C include那样。这是我的代码: 主要模块: use strict; our ($base); $base = '/home/en/dtest/perl/forditas/utf8/forditas/test1'; require("$base/disph1.pl"); require("$base/fu
use strict;
our ($base);
$base = '/home/en/dtest/perl/forditas/utf8/forditas/test1';
require("$base/disph1.pl");
require("$base/fut1h1.pl");
for (my $j = 0; $j < 5; $j++){
dispatch($j);
}
for (0..4) #equivalent to before, but more Perlish.
{
dispatch($_);
}
功能模块:
use strict;
our ($sref1, $sref2, $sref3, $sref4, $sref5); # This is what I'd like to include
$sref1 = sub($$$) {
my ($a,$b,$c) = @_;
print "sub1 $a,$b,$c\n";
};
$sref2 = sub($$$) { my ($a,$b,$c) = @_; print "sub2 $a, $b, $c\n"; };
$sref3 = sub { print "sub3\n"; };
$sref4 = sub { print "sub4\n"; };
$sref5 = sub { print "sub5\n"; };
1;
这是运行的结果:
$ perl enhufh1.pl
sub1 1,2,3
sub2 1, 2, 3
sub3
sub4
sub5
提前感谢您提供的提示。您需要的是
在您的模块中:
require Exporter;
@EXPORT = qw($sref1 $sref2 $sref3);
但是,可能值得考虑不同的设计:
脚本:
set_dispatch(0,sub{ .... });
调度程序模块:
my @dispatch; #If just indexing to numbers, use an array instead of a hash.
sub set_dispatch {
$dispatch[$_[0]] = $_[1];
}
主要模块:
use strict;
our ($base);
$base = '/home/en/dtest/perl/forditas/utf8/forditas/test1';
require("$base/disph1.pl");
require("$base/fut1h1.pl");
for (my $j = 0; $j < 5; $j++){
dispatch($j);
}
for (0..4) #equivalent to before, but more Perlish.
{
dispatch($_);
}
在我看来,使用函数调用来设置分派函数比导出一堆变量要好。您真的应该使用Perl模块-
*.pm
文件,并在需要时使用它们。使这些模块成为的子类允许它们将变量和原始名称导出到调用包中
看看这三个源代码集,它们还对原始代码进行了一些改进
请注意,您可以使用@EXPORT
数组而不是@EXPORT\u OK
,在这种情况下,相应的use
语句不必列出要导入的符号。但是,最好在使用点列出符号,否则必须检查模块的代码以准确发现导入的内容
main.pl
use strict;
use warnings;
use lib '/home/en/dtest/perl/forditas/utf8/forditas/test1';
use Dispatcher qw/ dispatch /;
dispatch($_) for 0 .. 4;
/home/en/dtest/perl/forditas/utf8/forditas/test1/Dispatcher.pm
package Dispatcher;
use strict;
use warnings;
require Exporter;
our @ISA = qw/ Exporter /;
our @EXPORT_OK = qw/ dispatch /;
use Utils qw/ sub1 sub2 sub3 sub4 sub5 /;
my @dtable = ( \&sub1, \&sub2, \&sub3, \&sub4, \&sub5 );
sub dispatch {
my ($i) = @_;
my ($a, $b, $c) = (1, 2, 3);
$dtable[$i]($a, $b, $c);
}
1;
package Utils;
use strict;
use warnings;
require Exporter;
our @ISA = qw/ Exporter /;
our @EXPORT_OK = qw/ sub1 sub2 sub3 sub4 sub5 /;
sub sub1 {
my ($a, $b, $c) = @_;
print "sub1 $a,$b,$c\n";
}
sub sub2 {
my ($a, $b, $c) = @_;
print "sub2 $a, $b, $c\n";
}
sub sub3 {
print "sub3\n";
}
sub sub4 {
print "sub4\n";
}
sub sub5 {
print "sub5\n";
}
1;
/home/en/dtest/perl/forditas/utf8/forditas/test1/Utils.pm
package Dispatcher;
use strict;
use warnings;
require Exporter;
our @ISA = qw/ Exporter /;
our @EXPORT_OK = qw/ dispatch /;
use Utils qw/ sub1 sub2 sub3 sub4 sub5 /;
my @dtable = ( \&sub1, \&sub2, \&sub3, \&sub4, \&sub5 );
sub dispatch {
my ($i) = @_;
my ($a, $b, $c) = (1, 2, 3);
$dtable[$i]($a, $b, $c);
}
1;
package Utils;
use strict;
use warnings;
require Exporter;
our @ISA = qw/ Exporter /;
our @EXPORT_OK = qw/ sub1 sub2 sub3 sub4 sub5 /;
sub sub1 {
my ($a, $b, $c) = @_;
print "sub1 $a,$b,$c\n";
}
sub sub2 {
my ($a, $b, $c) = @_;
print "sub2 $a, $b, $c\n";
}
sub sub3 {
print "sub3\n";
}
sub sub4 {
print "sub4\n";
}
sub sub5 {
print "sub5\n";
}
1;
输出
sub1 1,2,3
sub2 1, 2, 3
sub3
sub4
sub5
- 首先,将整数映射到元素是对哈希的滥用。您还可以使用数组
- 其次,您似乎希望将算法与实现分离,将它们连接到主脚本中。虽然这是令人钦佩的,但很明显,函数模块知道它的某些用途。因此,在导出一种知识图时,最简单的情况是您的功能模块知道dipatch模块
use strict;
use warnings;
our @EXPORT_OK = qw<setup_dispatch dispatch>;
use parent 'Exporter';
my @dispatch_subs;
sub setup_dispatch { @dispatch_subs = @_; }
sub dispatch {
my ($a, $b, $c) = ( 1, 2, 3 );
return $dispatch_subs[shift()]->( $a, $b, $c );
}
您可以在主模块中同时使用这两个选项,如下所示:
use strict;
use warnings;
require 'plugin_functions.pl';
use Dispatch qw<dispatch>;
...
使用严格;
使用警告;
需要“plugin_functions.pl”;
使用调度qw;
...
如果您只想使用“索引的”通用名称,那么您真的不需要“名称”。把它们列在一个清单上 第一个模块名为enhufh1.pl,第二个模块(dispatcher)名为disph1.pl,第三个模块(function module)名为fut1h1.pl。除非您确切知道子例程原型的功能,否则不要使用子例程原型。这里当然不需要它们-
子调度{…}
很好。非常感谢,您的解决方案非常好,因为我不需要修改我的子例程。您的解决方案比我的解决方案性能高10%。我仍然觉得很难看,我必须在Utils.pm和dispatcher.pm中声明函数名。我有大约800个函数名,它们的声明使模块不那么容易阅读。@eleonora:正如我在回答中所指出的,如果您在Utils
中使用@EXPORT
而不是@EXPORT\u OK
而不是Utils
中使用use-Utils
,那么您就可以在Dispatcher
中编写use-Utils
,它将导入该列表中的所有内容。但这被认为是一种不好的做法,因为在调度程序中不再有任何内容来说明导入了哪些符号。@eleonora:请注意@EXPORT
和@EXPORT\u OK
的行为与普通数组一样,因此如果您的子例程名称有共同之处,您可以在循环中构建它们。例如,在上面的代码中,您可以编写our@EXPORT=map“sub$\uz”,1..5