实现 Perl `implies` 宏或运算符

问题描述 投票:0回答:1

(我读过用 Perl 编写宏,但仍然需要指导)

Eiffel 有一个

implies
运算符(隐含布尔运算符,请参阅 ECMA-367 第 2 版中的 “8.5.20 语法:运算符”),即

a

implies
b

意义

not
a
or
b

所以第一次尝试是使用

# a implies b (a --> b)
sub implies($$)
{
    return !$_[0] || $_[1];
}

然而,这是一个函数,而不是一个运算符。 具体来说,对于像这样的情况,捷径评估会失败

implies(defined($a), $a eq '@')

(导致“在字符串 eq 中使用未初始化的值 $a ...”)。

所以问题是(对于 Perl 5.18.2): 有没有一种优雅的方式来向 Perl 添加这样一个“运算符”?

perl macros operators
1个回答
0
投票

您必须将表达式的计算推迟到子例程内部,或者隐藏错误。对于任意代码,隐藏错误可能很困难。但是通过使用代码参考来推迟评估是可行的:

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 '@'));
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.