如何扩展JSON::Tiny模块实现宽松JSON解析并复用原模块功能?
没问题,我来帮你搞定这个Perl 6扩展模块的需求!要实现JSON::Relaxed且完全复用JSON::Tiny的代码,我们可以分两步处理你提到的a)和b)要求:
解决a) 导出JSON::Tiny的所有内容
Perl 6的模块导出系统允许我们直接复用JSON::Tiny的导出集合,不需要手动逐个导出。我们可以通过赋值EXPORT::DEFAULT来把原模块的所有导出项传递给调用者。
解决b) 替换为自定义宽松语法规则
JSON::Tiny的解析逻辑依赖于它的语法规则类和动作处理类。我们只需要创建自己的语法类继承原JSON::Tiny::Grammar并覆盖指定规则,然后重新定义核心解析函数,让它们使用我们的宽松语法,同时复用原有的动作处理逻辑即可。
完整的JSON::Relaxed模块代码
unit module JSON::Relaxed; use v6; use JSON::Tiny; # 定义宽松语法,仅覆盖需要修改的规则 grammar JSON::Relaxed::Grammar is JSON::Tiny::Grammar { rule pairlist { <pair> * %% \, } # 允许键值对列表末尾带逗号 rule arraylist { <value> * %% \, } # 允许数组元素列表末尾带逗号 } # 重新定义parse函数,使用我们的宽松语法+原动作处理 sub parse(Str $json, :$actions = JSON::Tiny::Actions.new) is export { JSON::Relaxed::Grammar.parse($json, :$actions) } # 重新定义from-json,调用自定义的parse逻辑 sub from-json(Str $json) is export { my $parse-result = parse($json); $parse-result ?? $parse-result.made !! die "Invalid relaxed JSON syntax"; } # 导出JSON::Tiny的所有其他功能(比如to-json等) EXPORT::DEFAULT = JSON::Tiny::EXPORT::DEFAULT;
代码说明
- 语法扩展:
JSON::Relaxed::Grammar继承自原语法类,仅修改了pairlist和arraylist规则——用%%运算符替代原有的%,这样既保留了元素间用逗号分隔的规则,又允许末尾出现多余的逗号。 - 解析函数重写:我们重新定义了
parse和from-json两个核心入口函数,让它们使用我们的宽松语法,但复用原JSON::Tiny::Actions来处理解析结果,确保输出格式和原模块完全一致。 - 完整导出:最后一行
EXPORT::DEFAULT = JSON::Tiny::EXPORT::DEFAULT会把原模块的所有导出项(比如to-json)都传递过来,调用者使用use JSON::Relaxed就能获得和use JSON::Tiny一样的全部功能,同时支持宽松解析。
使用示例
use JSON::Relaxed; # 测试带末尾逗号的非标准JSON my $loose-obj = '{ "name": "Alice", "age": 30, }'; my %user = from-json($loose-obj); say %user; # 输出 {age => 30, name => Alice} my $loose-array = '[10, 20, 30,]'; my @nums = from-json($loose-array); say @nums; # 输出 [10, 20, 30] # 依然支持标准JSON和原模块的序列化功能 say to-json(%user); # 输出 {"age":30,"name":"Alice"}
内容的提问来源于stack exchange,提问作者Håkon Hægland
相关产品推荐
相关产品推荐

