如何将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
相关产品推荐
相关产品推荐

