首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何打印对象,输入nqp

如何打印对象,输入nqp
EN

Stack Overflow用户
提问于 2020-03-19 17:28:34
回答 2查看 122关注 0票数 7

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

  • 在Raku很容易做到:
代码语言:javascript
复制
1. [say](https://docs.raku.org/routine/say) that is calling [gist](https://docs.raku.org/routine/gist) in its short loop [code](https://github.com/rakudo/rakudo/blob/9429728cbd89e58bc85d88281985e44229fbcddb/src/core.c/io_operators.pm6#L24)
2. [dd](https://docs.raku.org/programs/01-debugging#Dumper_function_dd) The tiny Data Dumper as shown in this [post](https://stackoverflow.com/a/60707981/2544873)

代码语言:javascript
复制
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中似乎更复杂。
代码语言:javascript
复制
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);
代码语言:javascript
复制
Cannot stringify this object of type P6opaque (Titi)

当然,没有.gist方法,代码调用nqp::encode,它最终需要一个字符串。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-19 20:52:59

将问题降为MRE

代码语言:javascript
复制
class foo {}
say(foo.new); # Cannot stringify ...

简化解决方案:

代码语言:javascript
复制
class foo { method Str () { 'foo' } }
say(foo.new); # foo

总之,添加一个Str方法。

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

nqp对raku

上面的解决方案是raku使用的相同的技术;当一个值被例程/操作期望为字符串,但不是字符串时,语言行为就是试图胁迫一个字符串。具体来说,查看是否有可以对值调用的Str方法,如果可以,则调用它。

在本例中,NQPMuMu要简单得多,它没有提供任何默认的Str方法。因此,解决方案是手动添加一个。

更普遍地说,NQP是一种相当敌视的语言,除非您非常熟悉raku,并且已经通过Rakudo和NQP内部课程

一旦您掌握了这门课程的内容,我建议您将IRC频道#raku-dev和/或莫尔文作为您的第一个访问端口(除非您的目标是增加nqp/moarvm的覆盖范围)。

调试编译器代码

正如您将看到的,您链接的NQP代码在文件句柄上调用.say

然后调用这种方法

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

在NQP中搜索“无法字符串化”只匹配一些Java代码。我敢打赌你不会在JVM上运行Rakudo。这意味着错误消息必须来自MoarVM。

MoarVM回购中的相同搜索会产生在MoarVM中

回顾包含这一行的例程,我们看到这位

代码语言:javascript
复制
/* 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 (6模型)。

自定义Str方法

您需要酌情自定义Str方法。例如,如果类名是类型对象,则打印类名,否则打印其$!bar属性的值:

代码语言:javascript
复制
class foo {
  has $!bar;
  method Str () { self ?? nqp::coerce_is($!bar) !! self.HOW.name(self) }
}
say(foo.new(bar=>42)); # 42

尽管有方法名,nqp say例程并不期望一个raku Str,而是一个nqp本机字符串(它最终是MoarVM后端的MoarVM本机字符串)。因此,我需要nqp::coerce_is (我通过浏览nqp操作系统医生发现了这一点)。

self.HOW.name(self)是另一个例子,说明nqp不像raku那样有细微之处。您可以用raku编写相同的代码,但是用raku编写代码的惯用方法是self.^name

票数 7
EN

Stack Overflow用户

发布于 2020-03-19 17:35:49

目前,我有一个listhash鉴别器。它不适用于对象。

代码语言:javascript
复制
sub print_something ($value, :$indent = 0, :$no-indent=0) {
    if nqp::ishash($value) {
        print_hash($value, :$indent);
    } elsif nqp::islist($value) {
        print_array($value, :$indent);
    } else {
        if $no-indent {
            say($value);
        } else {
            say_indent($indent, $value);
        }
    }
}

哪里

代码语言:javascript
复制
sub print_indent ($int, $string) {
    my $res := '';
    my $i := 0;
    while $i < $int {
        $res := $res ~ '  ';
        $i := $i + 1;
    }
    $res := $res ~ $string;
    print($res);
}

sub print_array (@array, :$indent = 0) {
    my $iter := nqp::iterator(@array);
    say_indent($indent, '[');
    while $iter {
        print_value(nqp::shift($iter), :indent($indent+1));
    }
    say_indent($indent, ']');
}

sub print_hash (%hash, :$indent = 0) {
    my $iter := nqp::iterator(%hash);
    say_indent($indent, '{');
    while $iter {
        my $pair := nqp::shift($iter);
        my $key := nqp::iterkey_s($pair);
        my $value := nqp::iterval($pair);
        print_indent($indent + 1, $key ~ ' => ');
        print_value($value, :indent($indent+1), :no-indent(1));
    }
    say_indent($indent, '}');
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60762252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档