一些背景:我想扩展 JSON::Tiny 以允许更轻松的列表解析.这类似于Perl 5中 JSON::XS 的宽松标志.具体来说,我希望可以在列表末尾添加逗号.例如,{“a”:1,“b”:2,}.注意2之后的逗号,正常的
JSON::Tiny
以允许更轻松的列表解析.这类似于Perl 5中
JSON::XS
的宽松标志.具体来说,我希望可以在列表末尾添加逗号.例如,{“a”:1,“b”:2,}.注意2之后的逗号,正常的JSON语法规范(或JSON :: Tiny)不允许这样做.
通过检查source code,它似乎可以像扩展其中一个模块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 }
请注意,对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
在上面的评论中,实现a)和b)的最佳方法是什么?
你可以像这样单独引入语法和动作:use JSON::Tiny::Grammar; use JSON::Tiny::Actions;
然后像问题一样派生出你自己的语法.
使用生成的语法和现有的Actions类,你最终会得到
JSON::Relaxed::Grammar.parse($input, :actions(JSON::Tiny::Actions)).ast
请注意,在META6.json you can find the provides section中,它可以准确地告诉您可以使用的内容.
由于你想从JSON :: Tiny中获取原始的to-json,你必须导出一个转发到原始的to-json.这是执行此操作的代码:
sub to-json(|c) is export { use JSON::Tiny; to-json(|c); }
这将使得JSON :: Tiny中的符号仅在to-json函数的词法范围内可用,它将获取其所有参数并使用它们调用原始的to-json函数.