You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JSON布尔值解码为Perl布尔值?适配Perl≥5.36代码往返

Perl 5.36+ 实现原生布尔值的JSON往返序列化一致性

问题现象

使用Cpanel::JSON::XS处理Perl 5.36引入的原生布尔值(builtin::true/builtin::false)时,往返序列化后类型发生偏移:原对象中的原生布尔值,反序列化后变成了JSON::PP::Boolean对象,无法保持类型一致性。

测试代码及输出:

perl -MCpanel::JSON::XS=decode_json,encode_json -Mbuiltin=false,true -MDevel::Peek=Dump -E'
    say Cpanel::JSON::XS->VERSION;
    Dump { 23 => true };
    Dump decode_json encode_json { 23 => true };
'

输出结果:

4.39
SV = IV
  SV = PVHV
    Elt "23"
    SV = PVNV
      FLAGS = (IOK,NOK,POK,IsCOW,pIOK,pNOK,pPOK)
      PV = "1" [BOOL PL_Yes]
SV = IV
  SV = PVHV
    Elt "23"
    SV = IV
      SV = PVMG
        FLAGS = (OBJECT,IOK,READONLY,pIOK)
        IV = 1
        STASH = "JSON::PP::Boolean"

解决方案

通过配置Cpanel::JSON::XS的boolean_values选项,指定使用Perl原生布尔值完成序列化与反序列化,即可实现类型一致的往返处理。

修改后的测试代码:

perl -MCpanel::JSON::XS -Mbuiltin=false,true -MDevel::Peek=Dump -E'
    my $json = Cpanel::JSON::XS->new->boolean_values([\&true, \&false]);
    say $json->VERSION;
    my $original = { 23 => true };
    Dump $original;
    my $roundtripped = $json->decode($json->encode($original));
    Dump $roundtripped;
'

预期输出中,反序列化后的布尔值会保持原生PL_Yes类型,与原对象完全一致:

4.39
SV = IV
  SV = PVHV
    Elt "23"
    SV = PVNV
      FLAGS = (IOK,NOK,POK,IsCOW,pIOK,pNOK,pPOK)
      PV = "1" [BOOL PL_Yes]
SV = IV
  SV = PVHV
    Elt "23"
    SV = PVNV
      FLAGS = (IOK,NOK,POK,IsCOW,pIOK,pNOK,pPOK)
      PV = "1" [BOOL PL_Yes]

原理说明

Perl 5.36引入的原生布尔值是独立的类型标识(PL_Yes/PL_No),默认情况下Cpanel::JSON::XS会将其当作普通整数处理,反序列化时生成JSON::PP::Boolean兼容对象。通过boolean_values选项显式指定序列化和反序列化使用原生布尔值构造函数,模块就能正确识别并保留原生布尔类型,实现严格的往返一致性。

内容的提问来源于stack exchange,提问作者daxim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 07:53:09