请求 arrayref 时,perl 中捆绑散列的奇怪行为
Strange behavior of a tied hash in perl, when asking for an arrayref
我试图绑定一个散列(或散列引用)来跟踪变量的使用。
一切都适用于简单的情况,但是当我尝试在一些真实代码上使用我的模块时,我遇到了这个错误:
hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)
我使用以下代码重现了错误:
use Tie::Hash::Usages;
use JSON;
my @arr = (
{
key1 => "ac",
key2 => 12,
key3 => 12
},
);
my %tied_hash;
tie %tied_hash, 'Tie::Hash::Usages';
$tied_hash{key1} = \@arr;
my @val = $tied_hash{key1};
print encode_json(\@val)."\n\n"; #this works
print encode_json($tied_hash{key1}); #this doesn't
相同的代码适用于纯哈希。
我需要它在第二种情况下也能正常工作,代码库很大,我不想更改它,也不想在某些特定情况下某些地方无法正常工作。
Usages.pm(简体)
package Tie::Hash::Usages;
use strict;
use warnings;
use Tie::Hash;
use vars qw(@ISA);
@ISA = qw(Tie::StdHash);
sub TIEHASH {
my ($class, $tracker, $filename) = @_;
my %hash;
bless \%hash, $class;
}
sub STORE {
my ($self, $key, $val) = @_;
$self->{$key} = $val;
}
sub DELETE {
my ($self, $key) = @_;
delete $self->{$key};
}
sub FETCH {
my ($self, $key) = @_;
return $self->{$key};
}
sub DESTROY {
my $self = shift;
}
1;
perl 版本:v5.18.2
无法使用给定的代码进行复制,因此您提供的内容似乎不能代表您的实际情况。我唯一看到的是这一行:
my @val = $tied_hash{key1};
其中您将标量(您存储的数组引用)分配给数组。 Perl 处理得很好,将标量作为唯一内容组装一个数组,但如果您的实际用例涉及更复杂的东西(可能涉及子原型的东西),可以想象那里可能出了问题。
最少的演示:
use JSON::XS qw( encode_json );
use Tie::Hash qw( );
our @ISA = 'Tie::StdHash';
{
tie my %tied, __PACKAGE__;
$tied{data} = { a => 1 };
encode_json($tied{data}); # Exception: hash- or arrayref expected ...
}
JSON 是 JSON::PP(默认)或 JSON::XS(如果找到)的前端。这是 JSON::XS.
的问题
很多 XS 代码不处理魔法变量(这就是 $tied{EXPR}
returns),虽然 JSON::XS 从 1.2 版本开始处理魔法值,但它没有t 为直接传递给 encode_json
的值。
这是 JSON::XS 中的一个现有错误,可以通过以下方式解决:
encode_json(my $non_magical = $tied{data})
错误 reported。
Ether 做对了。 JSON 库默认使用 JSON:XS(这会造成此问题)。我所要做的就是卸载 JSON::XS 并安装 JSON::PP
- sudo cpan
- 安装 cpan App::cpanminus
- 退出
- sudo cpanm --uninstall JSON::XS
- sudo cpan
- 安装JSON::PP
- 退出
希望这对某人有所帮助。
我试图绑定一个散列(或散列引用)来跟踪变量的使用。
一切都适用于简单的情况,但是当我尝试在一些真实代码上使用我的模块时,我遇到了这个错误:
hash- or arrayref expected (not a simple scalar, use allow_nonref to allow this)
我使用以下代码重现了错误:
use Tie::Hash::Usages;
use JSON;
my @arr = (
{
key1 => "ac",
key2 => 12,
key3 => 12
},
);
my %tied_hash;
tie %tied_hash, 'Tie::Hash::Usages';
$tied_hash{key1} = \@arr;
my @val = $tied_hash{key1};
print encode_json(\@val)."\n\n"; #this works
print encode_json($tied_hash{key1}); #this doesn't
相同的代码适用于纯哈希。
我需要它在第二种情况下也能正常工作,代码库很大,我不想更改它,也不想在某些特定情况下某些地方无法正常工作。
Usages.pm(简体)
package Tie::Hash::Usages;
use strict;
use warnings;
use Tie::Hash;
use vars qw(@ISA);
@ISA = qw(Tie::StdHash);
sub TIEHASH {
my ($class, $tracker, $filename) = @_;
my %hash;
bless \%hash, $class;
}
sub STORE {
my ($self, $key, $val) = @_;
$self->{$key} = $val;
}
sub DELETE {
my ($self, $key) = @_;
delete $self->{$key};
}
sub FETCH {
my ($self, $key) = @_;
return $self->{$key};
}
sub DESTROY {
my $self = shift;
}
1;
perl 版本:v5.18.2
无法使用给定的代码进行复制,因此您提供的内容似乎不能代表您的实际情况。我唯一看到的是这一行:
my @val = $tied_hash{key1};
其中您将标量(您存储的数组引用)分配给数组。 Perl 处理得很好,将标量作为唯一内容组装一个数组,但如果您的实际用例涉及更复杂的东西(可能涉及子原型的东西),可以想象那里可能出了问题。
最少的演示:
use JSON::XS qw( encode_json );
use Tie::Hash qw( );
our @ISA = 'Tie::StdHash';
{
tie my %tied, __PACKAGE__;
$tied{data} = { a => 1 };
encode_json($tied{data}); # Exception: hash- or arrayref expected ...
}
JSON 是 JSON::PP(默认)或 JSON::XS(如果找到)的前端。这是 JSON::XS.
的问题很多 XS 代码不处理魔法变量(这就是 $tied{EXPR}
returns),虽然 JSON::XS 从 1.2 版本开始处理魔法值,但它没有t 为直接传递给 encode_json
的值。
这是 JSON::XS 中的一个现有错误,可以通过以下方式解决:
encode_json(my $non_magical = $tied{data})
错误 reported。
Ether 做对了。 JSON 库默认使用 JSON:XS(这会造成此问题)。我所要做的就是卸载 JSON::XS 并安装 JSON::PP
- sudo cpan
- 安装 cpan App::cpanminus
- 退出
- sudo cpanm --uninstall JSON::XS
- sudo cpan
- 安装JSON::PP
- 退出
希望这对某人有所帮助。