Håk*_*and 4 inheritance grammar perl6 raku
一些背景:我想扩展JSON::Tiny以允许更轻松的列表解析.这类似于Perl 5中的relaxed标志JSON::XS.具体来说,我希望可以选择在列表末尾添加逗号.例如,{ "a" : 1, "b" : 2, }.注意之后的逗号2,正常的JSON语法规范(或JSON::Tiny)不允许这样做.
通过检查源代码,它似乎可以像扩展其中一个模块JSON :: Tiny :: Grammar一样简单,它JSON::Tiny在内部使用,然后覆盖其两个规则:
grammar JSON::Relaxed::Grammar is JSON::Tiny::Grammar {
rule pairlist { <pair> * %% \, } # override this rule
rule arraylist { <value> * %% [ \, ] } #overide this rule
}
Run Code Online (Sandbox Code Playgroud)
请注意,唯一的修改JSON::Tiny::Grammar是引入%%运算符而不是%操作符pairlist和arraylist规则.
这样的扩展将允许代码重用.(复制所有代码的替代方案JSON::Tiny是最后的选择.)
问题:现在的问题是如何在JSON::Relaxed不修改或复制代码的情况下创建扩展(调用 )JSON::Tiny?这是我想写的模块的草图:
unit module JSON::Relaxed;
use v6;
use JSON::Tiny; # <-- since it is a module, I cannot extend it like a class
# a) export all the stuff that JSON::Tiny exports to the caller
# b) Somehow make JSON::Tiny use JSON::Relaxed::Grammar instead of JSON::Tiny::Grammar
Run Code Online (Sandbox Code Playgroud)
在上面的评论中,实现a)和b)的最佳方法是什么?
你可以像这样单独引入语法和动作:
use JSON::Tiny::Grammar;
use JSON::Tiny::Actions;
Run Code Online (Sandbox Code Playgroud)
然后像问题一样派生出你自己的语法.
使用生成的语法和现有的Actions类,你最终会得到
JSON::Relaxed::Grammar.parse($input, :actions(JSON::Tiny::Actions)).ast
Run Code Online (Sandbox Code Playgroud)
请注意,在META6.json中,您可以找到提供部分,它可以准确地告诉您use.
既然你想利用原来to-json的JSON::Tiny,你将不得不导出to-json转发到原来的.这是执行此操作的代码:
sub to-json(|c) is export {
use JSON::Tiny;
to-json(|c);
}
Run Code Online (Sandbox Code Playgroud)
这将使符号JSON::Tiny仅在to-json函数的词法范围内可用,它将获取其所有参数并to-json使用它们调用原始函数.