gpt4 book ai didi

raku - 如何打印对象,输入 nqp

转载 作者:行者123 更新时间:2023-12-03 18:33:59 25 4
gpt4 key购买 nike

如何在 NQP 中打印对象? (用于调试目的)

  • 在 Raku 中很容易:
  • say正在调用 gist在其短循环中 code
  • dd微型数据转储器,如本 post 所示
  • class Toto { has $.member = 42; }
    class Titi { has $.member = 41; has $.toto = Toto.new }
    my $ti = Titi.new;
    say $ti;
    # Titi.new(member => 41, toto => Toto.new(member => 42))
    dd $ti;
    # Titi $ti = Titi.new(member => 41, toto => Toto.new(member => 42))
  • 在 NQP 中似乎更复杂
  • class Toto { has $!member; sub create() {$!member := 42}};
    class Titi { has $!member; has $!toto; sub create() {$!member := 41; $!toto := Toto.new; $!toto.create; }}
    my $ti := Titi.new;
    say($ti);
    Cannot stringify this object of type P6opaque (Titi)

    当然,没有 .gist方法, code电话 nqp::encode最终需要一个字符串。

    最佳答案

    将问题减少到 MRE :

    class foo {}
    say(foo.new); # Cannot stringify ...

    简化解决方案:
    class foo { method Str () { 'foo' } }
    say(foo.new); # foo

    总之,添加一个 Str方法。

    这听起来很简单,但有很多幕后的东西需要考虑/解释。

    nqp vs 乐

    上述解决方案与 raku 使用的技术相同;当例程/操作期望值是字符串但不是字符串时,语言行为是尝试强制转换为字符串。具体看有没有 Str可以对值调用的方法,如果是,则调用它。

    在这种情况下 NQP's NQPMu ,这比 raku's Mu 更准系统, 不提供任何默认值 Str方法。所以一个解决办法是手动添加一个。

    更一般地说,NQP 是一种非常敌对的语言,除非您相当了解 raku 并且已经通过 A course on Rakudo and NQP internals .

    一旦您掌握了该类(class)中的内容,我建议您考虑 IRC channel #raku-dev和/或 #moarvm作为您的第一个停靠港而不是 SO(除非您的目标是专门增加 nqp/moarvm 的 SO 覆盖范围)。

    调试编译器代码

    如您所见,您链接的 NQP 代码调用了 .say在文件句柄上。

    然后调用 this method .

    该方法的主体是 $str ~ "\n" .该代码将试图强制 $str到字符串(就像在 raku 中一样)。这就是产生“无法字符串化”错误的原因。

    在 NQP 存储库中搜索“Cannot stringify”仅匹配一些 Java 代码。而且我敢打赌你不是在 JVM 上运行 Rakudo。这意味着错误消息必须来自 MoarVM。

    MoarVM 存储库中的相同搜索产生 this line in coerce.c in MoarVM .

    回顾包含该行的例程,我们看到 this bit :
    /* Check if there is a Str method. */
    MVMROOT(tc, obj, {
    strmeth = MVM_6model_find_method_cache_only(tc, obj,
    tc->instance->str_consts.Str);
    });

    这显示了用 C 编写的后端,寻找并调用名为 Str 的“方法”。 . (它依赖于编译器的所有三层(raku、nqp 和后端)都遵循的内部 API(6model)。)

    定制 Str方法

    您需要自定义 Str适当的方法。例如,如果它是一个类型对象,则打印类的名称,以及它的值 $!bar否则属性:
    class foo {
    has $!bar;
    method Str () { self ?? nqp::coerce_is($!bar) !! self.HOW.name(self) }
    }
    say(foo.new(bar=>42)); # 42

    尽管有方法名称,nqp say例行公事不期待乐 Str而是一个 nqp native 字符串(最终成为 MoarVM 后端的 MoarVM native 字符串)。因此需要 nqp::coerce_is (我通过浏览 the nqp ops doc 找到的)。
    self.HOW.name(self)是 nqp 没有 raku 的优点的另一个例子。您可以在 raku 中编写相同的代码,但在 raku 中编写它的惯用方法是 self.^name .

    关于raku - 如何打印对象,输入 nqp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60762252/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com