Perl:调用模块子例程的符号子引用的正确方法?



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

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

在您的主perl程序(例如test.pl)中,将值分配给子ref并调用它,或者以其他方式调用default的正确方法是什么?

sub call_proc {
   my $args   = shift;
   my $subref = $args->{proc_name} // 'default';
   &$Foo::subref();                               # <====== Wrong
}
call_proc({ proc_name => q{foo} });               # make the call

我已经用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} });      

&$name不被严格的refs捕获,因此:

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();
}

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

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

最新更新