如何测试给定参数是否是子程序?
例如:
sub foo {
my $bar = shift;
if (is_subroutine($bar)) {
return &$bar();
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我会这样称呼它:
foo(sub { print "Hi!" }); # prints "Hi!"
foo(123); # Nothing
Run Code Online (Sandbox Code Playgroud)
我怎样才能做到这一点?
核心Scalar::Util中给出了一些处理引用的工具
use Scalar::Util qw(reftype);
my $cr = sub { say "hi @_" };
say reftype $cr; #--> CODE
Run Code Online (Sandbox Code Playgroud)
返回的变量不是引用,因此首先测试该reftype变量undef
sub is_subroutine {
my $rt = reftype $_[0];
return defined $rt and $rt eq 'CODE'
}
Run Code Online (Sandbox Code Playgroud)
(但如果这仅在问题中的短子中使用,则不需要另一个子)
那么在这种情况下使用ref可能会更简单,因为它返回一个空字符串作为非引用,所以你可以这样做
if (ref $var eq 'CODE')
Run Code Online (Sandbox Code Playgroud)
也就是说,除非可能bless混合有 -ings,例如受祝福的代码引用或充当子例程的对象,其ref仅返回类的名称,而reftype返回基础类型。
许多Scalar::Util函数(以及其他函数)都可以通过较新 Perls 中的实验核心内置::reftype pragma/namespace 获得,包括(v5.36)