我正试图弄清楚上述例程之间的区别,以及像下面这样的if语句。
say $y.Bool;
say $y.so;
say ? $y;
say so $y;
到目前为止,我所发现的唯一差异是 ?
的优先级高于 so
。 .Bool
和 .so
看起来完全同义。这是否正确,从实际角度而言,这就是全部内容了吗?
我正试图弄清楚上述例程之间的区别,以及像下面这样的if语句。
say $y.Bool;
say $y.so;
say ? $y;
say so $y;
到目前为止,我所发现的唯一差异是 ?
的优先级高于 so
。 .Bool
和 .so
看起来完全同义。这是否正确,从实际角度而言,这就是全部内容了吗?
so
是字母,而?
是标点符号。要查看控制此解析的精确代码,请查看Rakudo's Grammar.nqp
并在该页面中搜索prefix:sym<...>
,其中...
是?
、so
等。看起来三元运算(... ?? ... !! ...
)会转换成一个if
。我发现这些标记都没有相应命名的Actions.pm6
方法。作为一个有些猜测的人,也许与它们对应的代码生成是由method EXPR
的这一部分处理的。 (有人知道吗,或者愿意按照这篇博客文章的说明找出来吗?)
在 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
。?
的布尔位运算符。它们与您的问题相差甚远,但它们的代码包含在上面的链接中。