在阅读一些JSON数据结构,然后使用Dump
尝试YAML::Tiny
时,我有时会收到错误
YAML::Tiny does not support JSON::XS::Boolean
我理解为什么会出现这种情况(特别是YAML::Tiny
不支持布尔值,JSON
希望明确区别于其他标量),但有一个快速的黑客可以转换那些JSON::XS::Boolean
1}}对象转换为普通0
和1
只是为了快速转储到屏幕目的?
答案 0 :(得分:3)
YAML::Tiny不支持对象。不幸的是,它甚至没有选项来对所有对象进行字符串化处理,这些对象将处理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不会生成它们。它也不会检查对象是否实际上有重载的字符串化。
Data::Rmap对此无效,因为无论出现多少次,它都只会访问一次特定对象。由于JSON::XS::Boolean
个对象是单例,这意味着它只会找到第一个true
和第一个false
。可以解决这个问题,但是需要深入研究源代码以确定如何在其seen
哈希中生成密钥:
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
中的更改的影响。