raku - 内省(introspection)捕获的更好方法

标签 raku introspection

我想测试签名中第一个对象的类型。以下显示了我发现的一些方法。但是为什么对类型(以下 3 个测试中的第 2 个)的智能匹配不起作用?
有没有比对 Type 等效的字符串进行字符串化和测试更好的方法?
(以下是我正在处理的用例)

raku -e "sub a( |c ) { say so |c[0].WHAT.raku ~~ /'Rat'/, so |c[0].WHAT ~~ Rat, so |c[0].^name ~~ /'Rat'/ };a(3/2);a(2)"
TrueFalseTrue
FalseFalseFalse
# OUTPUT:
#TrueFalseTrue
#FalseFalseFalse
我正在写 proto sub handle ,并且大多数潜艇具有相似的签名,例如。 multi sub handle( Pod $node, MyObj $p, Int $level --> Str)因此,大多数多潜艇根据 $node 中的内容做不同的事情。但是,handle 的情况如何处理?用 Nil 调用或纯字符串。我正在考虑类似的事情
proto handle(|c) {
    if |c[0].^name ~~ /'Str'/ { # code for string }
    else { {*} }
}

最佳答案

A better way to introspect ...


一般来说,用任何编程语言做任何事情的更好方法是不要内省(introspection),如果你可以避免它。
一般来说,在 Raku 中,您可以避免手动自省(introspection)。请参阅 部分内省(introspection) 在此答案的末尾进行进一步讨论。

... a capture


获得捕获自省(introspection)提供的功能的最佳工具是使用签名。这是他们生活的主要目的。

I want to test the type of the first object in a signature


使用签名:
proto handle(|) {*}
multi handle( Pod $node )   { ... }
multi handle( Str $string ) { ... }
multi handle( Nil )         { ... }

The following shows some ways I have found that work.


虽然他们做你想做的事,但他们基本上忽略了 Raku 的所有标志性功能。它们将签名简化为与捕获的绑定(bind)作为单个结构;然后在例程的主体中使用该捕获的手动内省(introspection)。
使用签名几乎总是有一种更简单、更好的方法来做这些事情。

why does [|c[0].WHAT ~~ Rat, with c[0] == 3/2] not work?


我将首先简化,然后以您的代码在做什么结束:
say    3/2        ~~ Rat;  # True
say   (3/2)       ~~ Rat;  # True
say   (3/2).WHAT  ~~ Rat;  # True
say |((3/2).WHAT  ~~ Rat); # True
say (|(3/2).WHAT) ~~ Rat;  # False
say  |(3/2).WHAT  ~~ Rat;  # False
最后一种情况是因为|有更高的precedence~~ .

Is there a better way than stringifying and testing for the string equivalent of the Type?


天哪,是的。
使用类型,卢克。
(在您的用例中,请使用签名。)
内省(introspection)
与在例程主体中手动检查传入数据的代码相比,适当使用签名通常会:
  • 更好地阅读;
  • 生成更好的低级代码;
  • 在编译阶段进行部分或全部评估。

  • 如果一种语言及其编译器通过提供特定功能(例如签名)来解决用例,那么使用该功能而不是自省(introspection)通常会带来上述三个好处。
    语言/编译器可以分为四类,即:
  • 不要进行或允许任何内省(introspection);
  • 允许编译器自省(introspection),但不允许开发者;
  • 允许编译器和开发人员进行自省(introspection),但目标是使其成为最后的手段,至少对开发人员而言;
  • 启用并鼓励开发人员进行自省(introspection)。

  • Raku(do) 属于第三类。在此 SO 的上下文中,签名是主要功能,几乎消除了开发人员手动自省(introspection)的任何需要。

    关于raku - 内省(introspection)捕获的更好方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62674228/

    相关文章:

    regex - Perl6 中的语法有点过于贪婪

    metaprogramming - 自省(introspection) : how do we get the name of a class within a class?

    C++ 和序列化 : is there any way to do some kind of introspection?

    python - 如何在 Python 中查看函数签名?

    python - 如何 "see"python中对象的结构

    c - 将包含函数名称及其参数的字符串传递给另一个函数。

    ruby - 在 ruby​​ 中,我怎么知道哪个模块被定义为 'load' 或 'require' 的结果?

    raku - 当使用 nextsame 或 callame 时,奇怪的 "Can' t use unknown trait

    asynchronous - 如何限制 Perl 6 中 Proc::Async 产生的并发进程数?

    types - 如何为角色组编写模块?