(我读过用 Perl 编写宏,但仍然需要指导)
Eiffel 有一个
implies
运算符(隐含布尔运算符,请参阅 ECMA-367 第 2 版中的 “8.5.20 语法:运算符”),即
a
bimplies
意义
anot
bor
所以第一次尝试是使用
# a implies b (a --> b)
sub implies($$)
{
return !$_[0] || $_[1];
}
然而,这是一个函数,而不是一个运算符。 具体来说,对于像这样的情况,捷径评估会失败
implies(defined($a), $a eq '@')
(导致“在字符串 eq 中使用未初始化的值 $a ...”)。
所以问题是(对于 Perl 5.18.2): 有没有一种优雅的方式来向 Perl 添加这样一个“运算符”?
您必须将表达式的计算推迟到子例程内部,或者隐藏错误。对于任意代码,隐藏错误可能很困难。但是通过使用代码参考来推迟评估是可行的:
use strict;
use warnings;
sub implies {
return !($_[0]->()) || $_[1]->();
}
print implies(sub { defined($a) }, sub { $a eq '@' });
将按预期工作。不会有错误,因为第二个代码引用由于
||
运算符短路而没有执行。这也许并不优雅,但我怀疑在不变得相当复杂的情况下尽可能优雅。
它也可能与 eval 一起使用。然后,评估将取决于变量是否在范围内正确。
sub implies {
return !(eval $_[0]) || eval $_[1];
}
print implies('defined($a)', q($a eq '@'));