DBM::Deep 无法导入具有 'true' 或 'false' 值的 hashref
DBM::Deep is failing to import hashref having 'true' or 'false' values
我有下面给出的 JSON
文本:
test.json
{
"a" : false
}
我想为上面的 JSON 创建 DBM::Deep
散列。我的代码如下所示:
dbm.pl
use strict;
use warnings;
use DBM::Deep;
use JSON;
use Data::Dumper;
# create the dbm::deep object
my $db = DBM::Deep->new(
file => 'test.db',
type => DBM::Deep->TYPE_HASH
);
my $json_text = do {
open( my $json_fh, $path )
or die("Can't open $path\": $!\n");
local $/;
<$json_fh>;
};
my $json = JSON->new;
my $data = $json->decode($json_text);
print Dumper($data);
# create dbm::deep hash
eval { $db->{$path} = $data; };
if ($@) {
print "error : $@\n";
}
我在执行上述代码时低于 output/error:
错误
$VAR1 = {
'a' => bless( do{(my $o = 0)}, 'JSON::XS::Boolean' )
};
error : DBM::Deep: Storage of references of type 'SCALAR' is not supported. at dbm.pl line 26
似乎,JSON 内部使用 JSON::XS 将 'true' 值转换为 JSON::XS::Boolean 对象,而 DBM::Deep 无法转换处理这个,同时它可以处理空值。
虽然上面的代码对于以下输入工作正常:
{
"a" : 'true' # if true is in quotes
}
或
{
"a" : null
}
我尝试了很多东西,但没有任何效果。有人有解决方法吗?
您正在使用的 JSON 解析器,除其他外,returns 在 [=21] 中遇到 true
或 false
时用作布尔值的对象=].这允许将数据重新编码为 JSON 而无需更改,但它可能会导致此类问题。
null
没有这个问题,因为 Perl 有一个原生值 (undef
) 可以用来明确地表示它。
下面将这些对象转换成简单的值。
sub convert_json_bools {
local *_convert_json_bools = sub {
my $ref_type = ref($_[0])
or return;
if ($ref_type eq 'HASH') {
_convert_json_bools($_) for values(%{ $_[0] });
}
elsif ($ref_type eq 'ARRAY') {
_convert_json_bools($_) for @{ $_[0] };
}
elsif ($ref_type =~ /::Boolean\z/) {
$_[0] = $_[0] ? 1 : 0;
}
else {
warn("Unsupported type $ref_type\n");
}
};
&_convert_json_bools;
}
convert_json_bools($data);
你的代码对我来说工作正常,唯一的变化是设置
my $path = 'test.json';
您应该检查您的模块版本号。这些是我拥有的
print $DBM::Deep::VERSION, "\n"; # 2.0013
print $JSON::VERSION, "\n"; # 2.90
print $JSON::XS::VERSION, "\n"; # 3.02
我是 运行 Perl v5.24.0
转储输出如下
新建DBM::Deep
数据库
$VAR1 = bless( {}, 'DBM::Deep::Hash' );
$json->decode
的输出
$VAR1 = {
'a' => undef
};
在eval
之后填充了DBM::Deep
数据库
$VAR1 = bless( {
'test.json' => bless( {
'a' => undef
}, 'DBM::Deep::Hash' )
}, 'DBM::Deep::Hash' );
所有这些看起来都应该如此
我有下面给出的 JSON
文本:
test.json
{
"a" : false
}
我想为上面的 JSON 创建 DBM::Deep
散列。我的代码如下所示:
dbm.pl
use strict;
use warnings;
use DBM::Deep;
use JSON;
use Data::Dumper;
# create the dbm::deep object
my $db = DBM::Deep->new(
file => 'test.db',
type => DBM::Deep->TYPE_HASH
);
my $json_text = do {
open( my $json_fh, $path )
or die("Can't open $path\": $!\n");
local $/;
<$json_fh>;
};
my $json = JSON->new;
my $data = $json->decode($json_text);
print Dumper($data);
# create dbm::deep hash
eval { $db->{$path} = $data; };
if ($@) {
print "error : $@\n";
}
我在执行上述代码时低于 output/error:
错误
$VAR1 = { 'a' => bless( do{(my $o = 0)}, 'JSON::XS::Boolean' ) }; error : DBM::Deep: Storage of references of type 'SCALAR' is not supported. at dbm.pl line 26
似乎,JSON 内部使用 JSON::XS 将 'true' 值转换为 JSON::XS::Boolean 对象,而 DBM::Deep 无法转换处理这个,同时它可以处理空值。
虽然上面的代码对于以下输入工作正常:
{
"a" : 'true' # if true is in quotes
}
或
{
"a" : null
}
我尝试了很多东西,但没有任何效果。有人有解决方法吗?
您正在使用的 JSON 解析器,除其他外,returns 在 [=21] 中遇到 true
或 false
时用作布尔值的对象=].这允许将数据重新编码为 JSON 而无需更改,但它可能会导致此类问题。
null
没有这个问题,因为 Perl 有一个原生值 (undef
) 可以用来明确地表示它。
下面将这些对象转换成简单的值。
sub convert_json_bools {
local *_convert_json_bools = sub {
my $ref_type = ref($_[0])
or return;
if ($ref_type eq 'HASH') {
_convert_json_bools($_) for values(%{ $_[0] });
}
elsif ($ref_type eq 'ARRAY') {
_convert_json_bools($_) for @{ $_[0] };
}
elsif ($ref_type =~ /::Boolean\z/) {
$_[0] = $_[0] ? 1 : 0;
}
else {
warn("Unsupported type $ref_type\n");
}
};
&_convert_json_bools;
}
convert_json_bools($data);
你的代码对我来说工作正常,唯一的变化是设置
my $path = 'test.json';
您应该检查您的模块版本号。这些是我拥有的
print $DBM::Deep::VERSION, "\n"; # 2.0013
print $JSON::VERSION, "\n"; # 2.90
print $JSON::XS::VERSION, "\n"; # 3.02
我是 运行 Perl v5.24.0
转储输出如下
新建DBM::Deep
数据库
$VAR1 = bless( {}, 'DBM::Deep::Hash' );
$json->decode
的输出
$VAR1 = {
'a' => undef
};
在eval
之后填充了DBM::Deep
数据库
$VAR1 = bless( {
'test.json' => bless( {
'a' => undef
}, 'DBM::Deep::Hash' )
}, 'DBM::Deep::Hash' );
所有这些看起来都应该如此