为什么我会收到此错误?

时间:2011-05-16 16:07:48

标签: perl json

这是我的代码

#!/usr/bin/perl -T

use CGI;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw(:standard);
use JSON;
use utf8;
use strict;
use warnings;


# ... ;

my $cgi = CGI->new;
$cgi->charset('UTF-8');

my @owners = map { s/\s*//g; $_ } split ",", $cgi->param('owner');
my @users  = map { s/\s*//g; $_ } split ",", $cgi->param('users');


my $json = JSON->new;
$json = $json->utf8;


my %user_result = ();
foreach my $u (@users) {
    $user_result{$u} = $db1->{$u}{displayName};
}

my %owner_result = ();
foreach my $o (@owners) {
    $owner_result{$o} = $db2{$o};
}

$json->{"users"}   = $json->encode(\%user_result);
$json->{"owners"}  = $json->encode(\%owner_result);

$json_string = to_json($json);

print $cgi->header(-type => "application/json", -charset => "utf-8");
print $json_string;

和这些行

$json->{"users"}   = $json->encode(\%user_result);
$json->{"owners"}  = $json->encode(\%owner_result);

给出错误

Not a HASH reference

为什么我会这样做?

如何修复?

4 个答案:

答案 0 :(得分:7)

JSON对象(至少在XS版本中,见下文)只是一个SCALAR引用,因此您无法对其执行哈希引用操作。实际上,您遇到的大多数Perl对象都是哈希引用,但情况并非总是如此。

我不确定您要通过使用JSON对JSON对象进行编码来实现目标。您需要编码JSON对象的内部吗?或者您只需要序列化用户和所有者数据?在后一种情况下,您应该使用新的哈希引用来保存该数据并传递给JSON。如果你确实需要对JSON对象进行编码,那么使用JSON::PP(JSON模块的“Pure Perl”变体)可能会有更好的运气,它使用哈希引用。

答案 1 :(得分:2)

在我看来$json = $json->utf8;正在用标量取代$ json hash ref,结果是$ json-> utf8。

在分配给$ json-> {...}的行之前,使用Data :: Dumper模块中的Dumper来查看其中的内容。

use Data::Dumper;
print Dumper($json);

答案 2 :(得分:2)

因为你的案例中的$ json是编码器本身,它是对SCALAR的引用。尝试使用不同的变量来保存结果。像

这样的东西
my %json_result = (users => $json->encode(\%user_result),
                   owners => $json->encode(\%owner_result));

答案 3 :(得分:2)

你的大问题是$json是JSON编码器对象,而不是要编码的数据结构。你应该建立一个单独的数据结构。

您的另一个问题是您正在尝试对JSON进行双重编码。这段代码:

my $data; # I've added this to fix your first bug
$data->{"users"}   = $json->encode(\%user_result);
$data->{"owners"}  = $json->encode(\%owner_result);

$json_string = to_json($data);

会创建一个JSON字符串,在解码时会给你一个带有两个键的哈希值。每个键的值将是包含JSON编码的哈希的字符串。将每个值作为哈希更有意义。

所以,试试这个:

my $json_string = $json->encode({
  users  => \%user_result,
  owners => \%owner_result,
});

这里,我使用匿名hashref,因为没有必要给哈希编码一个名字。我们只使用过一次。