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块中调用它,但是随后必须仔细检查$@以确定它是否失败,因为它不是子例程引用(因此回落为简单的标量),而被调用的子例程在某些情况下失败了原因(应该传播错误)。
当然,在这种情况下,由于旧值是一个非引用,因此我可以假定任何引用都是可调用的,但是我想要一个通用的解决方案(因为在以前它是哈希引用之前,我曾使用过这种方法)。有没有简单可靠的方法来测试标量是否“可执行”?
您可以尝试通过取消引用而不是将其作为子例程运行来进行检查。
my $is_code = ref $ref && do { local $@; eval { $ref = \&$ref; 1 } };
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您不必关心错误是什么,而只关心是否发生错误。\&$ref足够了,但是通过将结果分配回给$ref您,可以避免在调用该代码引用时再次调用重载。本地化$@仅出于礼貌。
如在我的Autoload :: AUTOCAN模块中使用的那样,原始信用为haarg。