如何测试给定的参数是否是子例程?例如:
sub foo { my $bar = shift; if (is_subroutine($bar)) { return &$bar(); } return 0; }
我会把这个叫做:
foo(sub { print "Hi!" }); # prints "Hi!" foo(123); # Nothing
我该怎么做?
qvk1mo1f1#
核心Scalar::Util中提供了一些使用引用的工具。
use Scalar::Util qw(reftype); my $cr = sub { say "hi @_" }; say reftype $cr; #--> CODE
reftype返回一个变量的undef,该变量不是一个引用,所以首先测试它
reftype
undef
sub is_subroutine { my $rt = reftype $_[0]; return defined $rt and $rt eq 'CODE' }
(but如果这是只用于短子像在问题中那么没有必要为另一个子)在这种情况下,使用ref可能会更简单,因为它返回一个空字符串作为非引用,所以您可以直接执行以下操作
if (ref $var eq 'CODE')
除非,也就是说,可能有bless-ings混合在其中,比如一个受祝福的代码引用或一个充当子例程的对象,对于这些对象,ref只返回类名,而reftype返回底层类型。许多Scalar::Util函数(沿着其他函数)可以在较新的Perl中使用实验性核心builtin:: pragma/namespace,包括reftype(v5.36)
bless
ref
Scalar::Util
jm81lzqq2#
您可以尝试使用&{...}将标量解引用为子例程,然后检查结果是否存在。
&{...}
if (exists &{$bar}) { ... }
此外,$bar()不是调用存储在标量引用中的子例程的有效语法。您需要编写&{$bar}()或$bar->()(后者是前者的sugar)
$bar()
&{$bar}()
$bar->()
2条答案
按热度按时间qvk1mo1f1#
核心Scalar::Util中提供了一些使用引用的工具。
reftype
返回一个变量的undef
,该变量不是一个引用,所以首先测试它(but如果这是只用于短子像在问题中那么没有必要为另一个子)
在这种情况下,使用ref可能会更简单,因为它返回一个空字符串作为非引用,所以您可以直接执行以下操作
除非,也就是说,可能有
bless
-ings混合在其中,比如一个受祝福的代码引用或一个充当子例程的对象,对于这些对象,ref
只返回类名,而reftype
返回底层类型。许多
Scalar::Util
函数(沿着其他函数)可以在较新的Perl中使用实验性核心builtin:: pragma/namespace,包括reftype
(v5.36)jm81lzqq2#
您可以尝试使用
&{...}
将标量解引用为子例程,然后检查结果是否存在。此外,
$bar()
不是调用存储在标量引用中的子例程的有效语法。您需要编写&{$bar}()
或$bar->()
(后者是前者的sugar)