Perl:将符号子参数调用到模块的子例程的正确方法是什么?

时间:2012-08-30 19:53:49

标签: perl

假设你有一个带有包Foo 的模块(例如 Foo.pm )。内部存在许多子例程定义,包括 foo 默认的子定义。

package Foo;
sub foo     { ... }
sub default { ... }

在主要的perl程序中(例如 test.pl ),为subref值分配并调用它或以其他方式调用默认值的正确方法是什么?

sub call_proc {
   my $args   = shift;
   my $subref = $args->{proc_name} // 'default';

   &$Foo::subref();                               # <====== Wrong
}
call_proc({ proc_name => q{foo} });               # make the call

3 个答案:

答案 0 :(得分:2)

我用UNIVERSAL::can

完成了这项工作
sub call_proc {
   my $args   = shift;
   my $subref = Foo->can($args->{proc_name}) // 'default';

   if ($subref) {
       &$subref();
   }
}
call_proc({ proc_name => q{foo} });      

答案 1 :(得分:1)

如果$subrefsome_method_name,则&$subref(或$subref->())将尝试在当前包中调用名为some_method_name 的函数< / em>的。根据程序的设置方式,您可能希望传递一个完全限定的子程序名称

call_proc( { proc_name => 'Foo::foo' });

或将一些逻辑放入call_proc以限定它。请参阅Forks::Super::Util中的qualify_sub_name功能,了解如何执行此操作。

您还可以安全地使用对函数的引用

call_proc( { proc_name => \&foo } );   # works if &foo is avail in current pkg

答案 2 :(得分:1)

\&$name没有被严格的引用捕获,所以:

sub call_proc {
   my $args     = shift;
   my $sub_name = $args->{proc_name} // 'default';
   my $sub_ref  = \&{ "Foo::" . $sub_name };
   #die if !defined(&$sub_ref);
   return $sub_ref->();
}

如果我们谈论方法,那就是:

sub call_method {
   my $args        = shift;
   my $method_name = $args->{method_name} // 'default';
   #die if !Foo->can($method_name);
   return Foo->$method_name();
}