perl中的分派函数,如何包含我们的列表

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

我发现在perl中分派许多函数的最快方法是使用函数引用。 剩下的问题是,我必须在分派器和函数模块中的($func1,$func2,…)列表中包含函数名。我无法找到任何方法来包含它们,就像C include那样。这是我的代码: 主要模块:

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