关于在Perl中使用函数数组
我们正在尝试构建一个API来自动支持commit()和rollback(),这样我们就不必再为它操心了。通过研究,我们发现使用关于在Perl中使用函数数组,perl,arrays,function,scope,concept,Perl,Arrays,Function,Scope,Concept,我们正在尝试构建一个API来自动支持commit()和rollback(),这样我们就不必再为它操心了。通过研究,我们发现使用eval{}是一条可行之路 为了让eval{}知道该做什么,我考虑过给API一个函数数组,它可以使用foreach执行该数组,而无需API进行任何解释。但是,此函数可能位于不同的包中 让我举例说明: sub handler { use OSA::SQL; use OSA::ourAPI; my @functions = (); push(@
eval{}
是一条可行之路
为了让eval{}
知道该做什么,我考虑过给API一个函数数组,它可以使用foreach
执行该数组,而无需API进行任何解释。但是,此函数可能位于不同的包中
让我举例说明:
sub handler {
use OSA::SQL;
use OSA::ourAPI;
my @functions = ();
push(@functions, OSA::SQL->add_page($date, $stuff, $foo, $bar));
my $API = OSA::ourAPI->connect();
$API->exec_multi(@functions);
}
问题是:是否可以在OSA::ourAPI
内部执行@functions
中的函数,即使我们的API没有使用OSA::SQL
。如果不是,那么如果指针指向内存中的已知函数,我是否可以使用数组引用而不是数组
注意:这是我们希望在更复杂的最终版本基础上的基本思想。- 您没有向数组添加函数指针。您正在添加调用add_page()子例程的返回值。您有3种解决方案:
A.需要(在
中)存储@functions
形式的数组引用,这意味着您将实际引用传递给子例程(静态调用);然后exec_multi将执行以下操作(语法可能不是100%正确,因为这里是凌晨4点)[\&OSA::SQL::add\u page,@argument\u values]
C.您需要(在
中)存储@functions
格式的数组引用,这意味着您要传入一个包和函数名;然后exec_multi将执行以下操作(语法可能不是100%正确,因为这里是凌晨4点) my($package,$sub,@args)=@{$functions[$i]}; 没有严格的“参考文献”; $package->$sub(@args); 使用严格的“refs”;[“OSA::SQL”,“add_page”,“argument_values]
- 如果我正确理解了您的问题,那么您就不必担心我们的API是否使用OSA::SQL,因为您的主代码已经导入了它
但是,由于在1B中,您将把包列表作为每个arrayref的第一个元素传递给exec#u multi,因此您可以在exec#u multi中执行“
”。但是,如果您的处理程序调用已经需要并加载了这些包中的每一个,那么这也是完全没有必要的。要正确执行此操作,还需要将参数列表传递给require$package;$package->import();
。但是为什么呢import()
- 您没有向数组添加函数指针。您正在添加调用add_page()子例程的返回值。您有3种解决方案:
A.需要(在
中)存储@functions
形式的数组引用,这意味着您将实际引用传递给子例程(静态调用);然后exec_multi将执行以下操作(语法可能不是100%正确,因为这里是凌晨4点)[\&OSA::SQL::add\u page,@argument\u values]
C.您需要(在
中)存储@functions
格式的数组引用,这意味着您要传入一个包和函数名;然后exec_multi将执行以下操作(语法可能不是100%正确,因为这里是凌晨4点) my($package,$sub,@args)=@{$functions[$i]}; 没有严格的“参考文献”; $package->$sub(@args); 使用严格的“refs”;[“OSA::SQL”,“add_page”,“argument_values]
- 如果我正确理解了您的问题,那么您就不必担心我们的API是否使用OSA::SQL,因为您的主代码已经导入了它
但是,由于在1B中,您将把包列表作为每个arrayref的第一个元素传递给exec#u multi,因此您可以在exec#u multi中执行“
”。但是,如果您的处理程序调用已经需要并加载了这些包中的每一个,那么这也是完全没有必要的。要正确执行此操作,还需要将参数列表传递给require$package;$package->import();
。但是为什么呢import()
eval
很少是解决问题的方法。。。将use
语句放入方法中不会将其执行延迟到方法运行时。当解析文件时,它会立即执行。我不明白你所说的“在OSA::ourAPI中执行给定函数”是什么意思。我编辑了我的问题以澄清。@functions中的函数就是我所说的那些函数。eval
很少是解决问题的方法。。。将use
语句放入方法中不会将其执行延迟到方法运行时。解析文件时立即执行。use$package代码>不合法。您可以将模块名转换为.pm文件的相对路径名,然后使用require
。最好让@functions只存储coderef,因此:push@functions,sub{OSA::SQL->add_page($date,$stuff,$foo,$bar)}代码>@ysth-LOL。。。是啊,我刚在发帖后意识到这两个问题;虽然我对第二个的解决方案略有不同。使用$package代码>不合法。您可以将模块名转换为.pm文件的相对路径名,然后使用require
。最好让@functions只存储coderef,因此:push@functions,sub{OSA::SQL->add_page($date,$stuff,$foo,$bar)}代码>@ysth-LOL。。。是啊,我刚在发帖后意识到这两个问题;虽然我对第二个问题的解决方案略有不同。
sub exec_multi {
my ($class, $funcs)= @_;
foreach my $f (@$funcs) {
my ($func, @args) = @$f;
my $res = &$func(@args);
print "RES:$res\n";
}
}
sub exec_multi {
my ($class, $funcs)= @_;
foreach my $f (@$funcs) {
my ($func) = @$f;
my $res = &$func();
print "RES:$res\n";
}
}
my ($package, $sub, @args) = @{ $functions[$i] };
no strict 'refs';
$package->$sub(@args);
use strict 'refs';