.Bool、.so、? 之间的区别是什么?涉及到 IT 技术。

10

我正试图弄清楚上述例程之间的区别,以及像下面这样的if语句。

say $y.Bool;
say $y.so;
say ? $y;
say so $y;

到目前为止,我所发现的唯一差异是 ? 的优先级高于 so.Bool.so 看起来完全同义。这是否正确,从实际角度而言,这就是全部内容了吗?

1个回答

8
我已经查看了Rakudo编译器源代码,以回答你的问题。
正如您所指出的,不同前缀之间的一个不同之处是解析差异。这些变化具有不同的优先级,so 是字母,而?是标点符号。要查看控制此解析的精确代码,请查看Rakudo's Grammar.nqp并在该页面中搜索prefix:sym<...>,其中...?so等。看起来三元运算(... ?? ... !! ...)会转换成一个if。我发现这些标记都没有相应命名的Actions.pm6方法。作为一个有些猜测的人,也许与它们对应的代码生成是由method EXPR的这一部分处理的。 (有人知道吗,或者愿意按照这篇博客文章的说明找出来吗?)

Bool.pm6中的定义Mu.pm6表明:

Mu.pm6 中,方法 .Bool 对于未定义的对象返回 False,否则返回 .defined。而 .defined 对于未定义的对象返回 False,否则返回 True。因此这些是默认值。
.defined 在两个内置类中被记录为重载 .Bool 在19个类中被记录
so.so? 都调用相同的代码,该代码延迟到 Bool/.Bool。理论上,类/模块可以覆盖它们,而不是或同时覆盖 .Bool.defined,但我无法看出为什么任何人都会在内置类/模块或用户空间中这样做。
not! 是相同的(除了 使用 :exists! 会导致死机),它们都转换为调用 nqp::hllbool(nqp::not_i(nqp::istrue(...)))。我认为它们不通过通常的 .Bool 路由的主要原因是避免 标记处理 Failure
Mu.pm6 中定义了 .so.not 方法。它们只是调用 .Bool
还有包含 ? 的布尔位运算符。它们与您的问题相差甚远,但它们的代码包含在上面的链接中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接