YAML :: Tiny不支持JSON :: XS :: Boolean

时间:2011-11-04 15:41:33

标签: json perl yaml

在阅读一些JSON数据结构,然后使用Dump尝试YAML::Tiny时,我有时会收到错误

YAML::Tiny does not support JSON::XS::Boolean

我理解为什么会出现这种情况(特别是YAML::Tiny不支持布尔值,JSON希望明确区别于其他标量),但有一个快速的黑客可以转换那些JSON::XS::Boolean 1}}对象转换为普通01只是为了快速转储到屏幕目的?

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中的更改的影响。