我试图弄清楚上述例程与if语句之类的区别
say $y.Bool;
say $y.so;
say ? $y;
say so $y;
将产生不同的结果。
到目前为止,对我而言,唯一显而易见的区别是?
的优先级高于so
。 .Bool
和.so
似乎是完全同义的。那是正确的,(实际上)是全文吗?
答案 0 :(得分:8)
我为回答您的问题所做的工作是拼写Rakudo编译器源代码。
您注意到,前缀之间的不同之处在于解析差异。变体具有不同的优先级,并且so
是字母,而?
是标点。要查看控制该解析的精确代码,请查看Rakudo's Grammar.nqp
并在该页面中搜索prefix:sym<...>
,其中...
是?
,so
等。看起来像ternary (... ?? ... !! ...
)变成if
。我看到这些标记都没有相应地命名为Actions.pm6
方法。作为一个有点疯狂的猜测,也许与它们相对应的代码生成是由this part of method EXPR
处理的。 (有人知道,还是愿意按照this blog post中的说明进行查找?)
definitions in Bool.pm6
和Mu.pm6
显示:
在Mu.pm6
中,方法.Bool
返回False
用于未定义对象,否则返回.defined
。反过来,.defined
为未定义的对象返回False
,否则返回True
。因此,这些是默认设置。
.defined
is documented as overridden in two built in classes和.Bool
in 19。
so
,.so
和?
都调用相同的代码,以符合Bool
/ .Bool
的要求。从理论上讲,类/模块可以覆盖它们,而不是覆盖.Bool
或.defined
,但是我看不出为什么有人会在内置的类/模块或用户级的。
not
和!
是相同的(除了use of !
with :exists
dies),它们都变成对nqp::hllbool(nqp::not_i(nqp::istrue(...)))
的调用。我认为他们不遵循常规的.Bool
路线的主要原因是避免使用marking handling of Failure
s。
在.so
中定义了.not
和Mu.pm6
个方法。他们只是打.Bool
。
存在包含?
的布尔按位运算符。它们与您的问题相距遥远,但是它们的代码包含在上面的链接中。