如何覆盖 NQPMatch.Str 函数

tin*_*ino 6 raku nqp

...或者如何从匹配的文本中独立地更改$<sigil>.Str值。是的,我在问如何欺骗上面的语法(即打电话给)我。token sigil { ... }

我正在尝试为 Raku编写一个没有 sigil俚语

所以我想要nogil令牌,匹配任何东西<?>以返回字符串化的 NqpMatch:$<sigil>.Str到 '$'。

目前,我的令牌符号看起来像这样

token sigil {
    | <[$@%&]>
    | <nogil> { say "Nogil returned: ", lk($/, 'nogil').Str; # Here It should print "$"
              }
}
token nogil-proxy {
    | '€'
    | <?>
    {log "No sigil:", get-stack; }
}
Run Code Online (Sandbox Code Playgroud)

并且带有该方法的方法应该返回一个NQPMatchwith 方法Str被覆盖

method nogil {
    my $cursor := self.nogil-proxy;
    # .. This si where Nqp expertise would be nice
    say "string is:", $cursor.Str;    # here also it should print "$"
    return $cursor;
}
Run Code Online (Sandbox Code Playgroud)

尝试失败:

$cursor.^cache_add('Str', sub { return '$'; } );
$cursor.^publish_method_cache;
for $cursor.^attributes { .name.say };
for $cursor.^methods { .name.say };
say $cursor.WHAT.Str;
nqp::setmethcacheauth($cursor, 0);
Run Code Online (Sandbox Code Playgroud)

目前,我的大多数测试都可以工作,但是我在没有我的 (with no strict) like 的声明中遇到了问题,my-var = 42;因为它们被视为方法调用。

@阿恩-索默已经做了一个帖子文章。这是密切相关的。但是这个问题的目的是:

我们如何自定义编译时标记的返回值,而不是如何声明它。

tin*_*ino 6

简介: @JonathanWorthington 指出的答案:

简介:使用mixin元函数。(而不是,但需要compose方法。)

演示:

  1. 通过检索另一个令牌创建一个 NQPMatch 对象:这里是sigil-my由 调用的令牌self.sigil-my
  2. ^mixin与角色一起使用
method sigil { return self.sigil-my.^mixin(Nogil::StrGil); }
Run Code Online (Sandbox Code Playgroud)

上下文:完全可重现的代码:

所以你可以看到什么类型是sigil-myNogil::StrGil。但我告诉过你:令牌(不仅仅是方法)和角色(不可实例化的类)。

role Nogil::StrGil {
    method Str() {
        return sigilize(callsame);
    }
}


sub EXPORT(|) {

# Save: main raku grammar
my $main-grammar = $*LANG.slang_grammar('MAIN');
my $main-actions = $*LANG.slang_actions('MAIN');

role Nogil::NogilGrammar {
    method sigil {
        return self.sigil-my.^mixin(Nogil::StrGil);
    }
}

token sigil-my { | <[$@%&]> | <?> }

# Mix
my $grammar = $main-grammar.^mixin(Nogil::NogilGrammar);
my $actions = $main-actions.^mixin(Nogil::NogilActions);
$*LANG.define_slang('MAIN', $grammar, $actions);

# Return empty hash -> specify that we’re not exporting anything extra
return {};

}
Run Code Online (Sandbox Code Playgroud)

注意:这为解决更多问题打开了大门(也由 jnthn 问题评论指出)-> -0fun !