如何检查Perl标量是否可以视为子例程?

der*_*ert 6 perl closures reference operator-overloading

我有一个最初只使用纯常数常量的API,但我对其进行了扩展,以便在使用时可以通过传递子例程引用来计算它。为了保持向后兼容性,我正在测试它是否是代码参考:

'CODE' eq ref($var)
    ? $var->()
    : $var;
Run Code Online (Sandbox Code Playgroud)

但我意识到不包括充当子例程的对象。像这样:

package Foo {
    sub new { bless {}, 'Foo' }
    use overload '&{}' => sub { sub { "Hello, world." } };
}
Run Code Online (Sandbox Code Playgroud)

我可以尝试在一个eval块中调用它,但是随后必须仔细检查$@以确定它是否失败,因为它不是子例程引用(因此回落为简单的标量),而被调用的子例程在某些情况下失败了原因(应该传播错误)。

当然,在这种情况下,由于旧值是一个非引用,因此我可以假定任何引用都是可调用的,但是我想要一个通用的解决方案(因为在以前它是哈希引用之前,我曾使用过这种方法)。有没有简单可靠的方法来测试标量是否“可执行”?

Gri*_*nnz 5

您可以尝试通过取消引用而不是将其作为子例程运行来进行检查。

my $is_code = ref $ref && do { local $@; eval { $ref = \&$ref; 1 } };
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您不必关心错误是什么,而只关心是否发生错误。\&$ref足够了,但是通过将结果分配回给$ref您,可以避免在调用该代码引用时再次调用重载。本地化$@仅出于礼貌。

如在我的Autoload :: AUTOCAN模块中使用的那样,原始信用为haarg。

  • 不,Perl API不应接受的东西可以是整数或子数。 (2认同)