在 Perl 中,是否可以对运算符进行子引用(例如 eq
或 gt
)?还是不可能因为他们不是潜艇?我想避免将运算符重新定义为需要比较函数的 subs。
我正在对配置值应用检查功能,其中检查器取决于配置键。一个这样的检查器是“与另一个键的值进行比较”。可以通过匿名子定义比较函数,或者可以为每个比较类型实现命名子,但我认为能够说 compare_to("OTHER_KEY",\&eq)
更好。
编辑:因为一位评论员想要上下文,而其他人投票认为关闭“过于宽泛”,我将绝对清楚问题不是“如何编写配置检查器”。这只是关于引用运算符:是否可能,有哪些注意事项?
最佳答案
eq
和 gt
等比较属于 CORE 函数的特殊类别,您无法在其中创建对它们的引用。这在此处的文档中有详细说明 http://perldoc.perl.org/CORE.html
所以看起来你不能做你想做的事。我认为您的选择包括:
- 使用匿名 subs 或命名 subs 来包装你要使用的比较器
- 传入字符串
'eq'
并在compare_to
中执行if
并在那里调用比较器。 - 您可以做一些其他语言做的事情,将第二个参数设置为 1、0 或 -1,并将其代表
gt
、eq
、lt
,然后如果该值是 coderef,则调用它。 - 如果您有兴趣沿着这条路走下去,可能有一种伪魔法方法可以使用
AUTOLOAD
来解决这个问题。
更新:
AUTOLOAD
魔法示例:
use feature qw( say );
my %bin_ops = map { $_ => 1 } qw( eq ne gt lt );
sub AUTOLOAD {
$AUTOLOAD =~ s/^.*:://;
die "..." if !$bin_ops{$AUTOLOAD};
return eval "\$_[0] $AUTOLOAD \$_[1]";
}
sub compare_to {
my ($sub, $a, $b) = @_;
return $sub->($a, $b);
}
say compare_to(\&eq, 1, 1) ? "yep" : "nope";
say compare_to(\&eq, 1, 0) ? "yep" : "nope";
say compare_to(\>, 1, 0) ? "yep" : "nope";
say compare_to(\<, 1, 0) ? "yep" : "nope";
运行它:
> perl tmp/test_coreref.pl
yep
nope
yep
nope
可能有一种方法可以在不使用 eval 的情况下做到这一点,但我暂时不打算进一步研究它。
关于perl - 引用 Perl 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40770839/