代码之家  ›  专栏  ›  技术社区  ›  Håkon Hægland

如何通过扩展模块所使用的类来扩展模块?

  •  4
  • Håkon Hægland  · 技术社区  · 7 年前

    一些背景: 我想延长 JSON::Tiny 允许更轻松地解析列表。这与 relaxed 的标志 JSON::XS 在Perl 5中。具体来说,我想在列表的末尾加一个逗号。例如 { "a" : 1, "b" : 2, } 。请注意 2 ,这是正常JSON语法规范所不允许的(或 JSON::微小 )。

    通过检查 source code 这似乎可以像扩展一个模块一样简单, JSON::Tiny::Grammar 那个 JSON::微小 正在内部使用,然后重写其两个规则:

    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::微小 是最后的手段。)

    问题 :现在的问题是如何创建扩展(调用 JSON::Relaxed )无需修改或复制 JSON::微小 ?下面是我想写的模块的草图:

    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)的最佳方法是什么?

    1 回复  |  直到 6 年前
        1
  •  5
  •   timotimo    7 年前

    你可以像这样分别输入语法和动作:

    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 这会告诉你你能做什么 use

    既然你想拿原件 to-json 从…起 JSON::Tiny ,您必须导出 至json 转发到原始版本。下面是实现此目的的代码:

    sub to-json(|c) is export {
        use JSON::Tiny;
        to-json(|c);
    }
    

    这将使符号 JSON::微小 仅在 至json 函数,它将只获取其所有参数并调用原始 至json 与他们一起工作。