Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
YAML::Tiny不支持JSON::XS::Boolean_Json_Perl_Yaml - Fatal编程技术网

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

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:

当读取一些JSON数据结构,然后尝试使用
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,谢谢!这就是我最后做的。谢谢你的解决方案!