.Bool、.so、? 之间的区别所以

Differences between .Bool, .so, ? and so

我想弄清楚上述例程之间的区别是什么,如果语句像

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

会产生不同的结果。

到目前为止,对我来说唯一明显的区别是 ? 的优先级高于 so.Bool.so 似乎完全是同义词。这是否正确并且(实际上)是完整的故事?

为了回答您的问题,我所做的工作是探查 Rakudo 编译器源代码。

正如您所注意到的,前缀之间的区别之一是解析差异。变体具有不同的优先级,so 是字母,而 ? 是标点符号。要查看控制此解析的精确代码,请查看 Rakudo's Grammar.nqp and search within that page for prefix:sym<...> where the ... is ?, so, etc. It looks like ternary (... ?? ... !! ...) turns into an if. I see that none of these tokens have correspondingly named Actions.pm6 methods. As a somewhat wild guess perhaps the code generation that corresponds to them is handled by this part of method EXPR. (Anyone know, or care to follow the instructions in this blog post 以找出答案?)

definitions in Bool.pm6 and Mu.pm6表明:

  • Mu.pm6 中,方法 .Bool returns False 用于未定义的对象,否则 .defined。对于未定义的对象依次 .defined returns False 否则 True 。所以这些是默认值。

  • .defined is documented as overridden in two built in classes and .Bool in 19.

  • so.so? 都调用遵循 Bool / .Bool 的相同代码。理论上 classes/modules 可以覆盖这些而不是覆盖 .Bool.defined,但我不明白为什么有人会在内置的 [=] 中这样做87=] 或用户空间。

  • not!是一样的(除了use of ! with :exists dies) and both turn into calls to nqp::hllbool(nqp::not_i(nqp::istrue(...))). I presume the primary reason they don't go through the usual .Bool route is to avoid marking handling of Failures.

  • Mu.pm6中定义了.so.not方法。他们只是打电话给 .Bool.

  • 有包含 ? 的布尔按位运算符。他们与你的问题相去甚远,但他们的代码包含在上面的链接中。