0

我发现在 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);
}

调度模块:

use strict;
our ($base);
require("$base/fut1h1.pl");

our ($sref1, $sref2, $sref3, $sref4, $sref5);  # This is what I'd like to include

my %shash = (
   '0' => $sref1,
   '1' => $sref2,
   '2' => $sref3,
   '3' => $sref4,
   '4' => $sref5,
);

sub dispatch($){
  my ($ix) = @_;
  my ($a, $b, $c);
  $a = 1; $b = 2; $c = 3;
  my $ref = $shash{$ix};
  &$ref($a,$b, $c);
}

1;

功能模块:

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

提前感谢您的提示。

4

3 回答 3

1

您确实应该使用 Perl 模块 -*.pm文件 - 并将它们包含在需要它们的地方use。使这些模块成为的子类Exporter允许它们将变量和子程序名称导出到调用包中。

看看这组三个来源,它们还为您的原始代码添加了一些改进。

请注意,您可以使用@EXPORT数组代替@EXPORT_OK,在这种情况下,相应的use语句不必列出要导入的符号。但是,最好在使用时列出符号,否则必须检查模块的代码以准确发现正在导入的内容。

主文件

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;

/home/en/dtest/perl/forditas/utf8/forditas/test1/Utils.pm

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
于 2013-02-01T11:50:00.670 回答
1
  • 首先,将整数映射到元素是对哈希的滥用。你也可以使用数组。

  • 其次,您似乎想将算法与实现隔离,将它们加入主脚本中。虽然这是令人钦佩的,但很明显,functions 模块知道它的用途。因此,在导出一种知识图谱时,最简单的情况是您的功能模块知道diapatch 模块。

您可以为此目的创建一个辅助函数:

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;
use Dispatch ();

Dispatch::setup_dispatch( 
  # I echo the caution about using prototypes
  sub ($$$) {   
     my ($a,$b,$c) = @_;
     print "sub1 $a,$b,$c\n"; 
  }
, sub ($$$) { my ($a,$b,$c) = @_; print "sub2 $a, $b, $c\n"; }
, sub {  print "sub3\n"; }
, sub {  print "sub4\n"; }
, sub {  print "sub5\n"; }
);

您只需在主模块中使用它们,如下所示:

use strict;
use warnings;
require 'plugin_functions.pl';

use Dispatch qw<dispatch>;

...

如果您只想使用“索引”通用名称,您真的不需要“名称”。只需将它们放在一个列表中。

于 2013-02-01T14:13:47.683 回答
0

你需要的是Exporter.

在您的模块中:

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];
}

主要模块:

for (0..4)    #equivalent to before, but more Perlish.
{
   dispatch($_);
}

在我看来,使用函数调用来设置调度函数比导出一堆变量要好。

于 2013-02-01T11:23:13.100 回答