我有一个最初只使用一个普通常量整数的API,但是我对其进行了扩展,以便在使用时可以通过传递子例程引用来计算它。为了保持向后兼容性,我正在测试它是否是代码参考:
'CODE' eq ref($var)
? $var->()
: $var;
但是我意识到不包括充当子例程的对象。像这样:
package Foo {
sub new { bless {}, 'Foo' }
use overload '&{}' => sub { sub { "Hello, world." } };
}
我可以尝试在eval
块中调用它,但是随后必须仔细检查$@
以确定它是否失败了,因为它不是子例程引用(因此回退到它)是一个简单的标量)与调用的子例程由于某种原因而失败(应该传播错误)。
当然,在这种情况下,由于旧值是一个非引用,因此我可以假定任何引用都是可调用的,但是我想要一个通用解决方案(因为我以前曾经使用过这种方法,是一个hashref)。是否有一种简单可靠的方法来测试标量是否“可执行”?
答案 0 :(得分:5)
您可以尝试通过取消引用而不是将其作为子例程运行来进行检查。
my $is_code = ref $ref && do { local $@; eval { $ref = \&$ref; 1 } };
在这种情况下,您不必关心错误是什么,而只关心是否发生错误。 \&$ref
就足够了,但是通过将结果分配回$ref
,可以避免在调用该代码引用时再次调用重载。本地化$@
只是出于礼貌。
与my Autoload::AUTOCAN module中使用的相同,但要归功于haarg。