YAML::Tiny不支持JSON::XS::Boolean
当读取一些JSON数据结构,然后尝试使用YAML::Tiny不支持JSON::XS::Boolean,json,perl,yaml,Json,Perl,Yaml,当读取一些JSON数据结构,然后尝试使用YAML::Tiny转储它们时,有时会出现错误 YAML::Tiny does not support JSON::XS::Boolean 我理解为什么会出现这种情况(特别是YAML::Tiny不支持boolean,而JSON渴望与其他标量明确区分),但是有没有一种快速的方法可以将那些JSON::XS::Boolean对象转换成普通的0和1,只用于快速转储到屏幕上?不支持对象。不幸的是,它甚至没有一个选项来仅仅字符串化所有对象,这将处理JSON::XS:
YAML::Tiny
转储它们时,有时会出现错误
YAML::Tiny does not support JSON::XS::Boolean
我理解为什么会出现这种情况(特别是YAML::Tiny
不支持boolean,而JSON
渴望与其他标量明确区分),但是有没有一种快速的方法可以将那些JSON::XS::Boolean
对象转换成普通的0
和1
,只用于快速转储到屏幕上?不支持对象。不幸的是,它甚至没有一个选项来仅仅字符串化所有对象,这将处理JSON::XS::Boolean
但是,使用递归函数可以相当容易地做到这一点:
use strict;
use warnings;
use 5.010; # for say
use JSON::XS qw(decode_json);
use Scalar::Util qw(blessed reftype);
use YAML::Tiny qw(Dump);
my $hash = decode_json('{ "foo": { "bar": true }, "baz": false }');
# Stringify all objects in $hash:
sub stringify_objects {
for my $val (@_) {
next unless my $ref = reftype $val;
if (blessed $val) { $val = "$val" }
elsif ($ref eq 'ARRAY') { stringify_objects(@$val) }
elsif ($ref eq 'HASH') { stringify_objects(values %$val) }
}
}
stringify_objects($hash);
say Dump $hash;
此函数不需要处理标量引用,因为JSON不会生成标量引用。它也不会检查对象是否确实重载了字符串化
这不适用,因为它只会访问特定对象一次,不管它出现多少次。由于JSON::XS::Boolean
对象是单例对象,这意味着它只能找到第一个true
和第一个false
。可以解决这个问题,但需要深入源代码以确定如何在其seen
hash中生成键:
use Data::Rmap qw(rmap_ref);
use Scalar::Util qw(blessed refaddr);
# Stringify all objects in $hash:
rmap_ref { if (blessed $_) { delete $_[0]->seen->{refaddr $_};
$_ = "$_" } } $hash;
我认为递归函数更清晰,而且它不容易受到
Data::Rmap
中更改的影响。我添加了一个与此相关的问题作为答案,以便发布代码。嗯。。实际上,如果其中一个值(例如,true
)出现多次,则它不起作用。出于某种原因,只有第一个布尔值被字符串化。知道为什么吗?@JuanAntonio,这是因为只有一个true
对象和一个false
对象。JSON::XS只是多次引用它。查看我的更新答案。@cjm,谢谢!这就是我最后做的。谢谢你的解决方案!