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
.