为什么JSON说缺少序列化挂钩?

时间:2017-07-03 09:15:12

标签: json perl dbix-class

运行cpanm --look DBIx::Class ; cd examples/Schema/以使用示例数据库。

use 5.024;
use strictures;
use JSON::MaybeXS qw(encode_json);
use MyApp::Schema qw();
use Sub::Install qw();

my $s = MyApp::Schema->connect('dbi:SQLite:db/example.db');
# Yes, I know Helper::Row::ToJSON exists.
Sub::Install::install_sub({
    code => sub {
        my ($self) = @_;
        return { map {$_ => $self->$_} keys %{ $self->columns_info } };
    },
    into => $s->source('Track')->result_class,
    as   => 'TO_JSON',
});

my ($t) = $s->resultset('Cd')->first->tracks;
say ref $t->can('TO_JSON'); # 'CODE', ok
say ref $t->TO_JSON;        # 'HASH', ok
say encode_json $t;
# encountered object 'MyApp::Schema::Result::Track=HASH(0x1a53b48)',
# but neither allow_blessed, convert_blessed nor allow_tags settings
# are enabled (or TO_JSON/FREEZE method missing) at …

我希望序列化程序找到已安装的钩子并使用它,但我得到上面的错误。出了什么问题?

1 个答案:

答案 0 :(得分:4)

为了让JSON::XS考虑TO_JSON,您必须明确启用convert_blessed选项:

my $coder = JSON::XS->new;
$coder->convert_blessed(1);
say $coder->encode($t);

根据docs

$json = $json->convert_blessed ([$enable])
$enabled = $json->get_convert_blessed
     

参见" OBJECT SERIALIZATION"详情。

     

如果$ enable为真(或缺失),则在遇到祝福对象时编码将检查TO_JSON方法的可用性   在对象的课上。如果找到,它将在标量上下文中调用   并且生成的标量将被编码而不是对象。

     

如果需要,TO_JSON方法可以安全地调用die。如果TO_JSON返回其他受祝福的对象,则将以相同的方式处理这些对象。   TO_JSON必须注意不要导致无休止的递归循环(==   崩溃)在这种情况下。选择TO_JSON的名称是因为其他   Perl核心调用的方法(==不是由对象的用户)   通常用大写字母表示,避免与任何to_json冲突   功能或方法。

     

如果 $ enable为false(默认值),则编码将不会考虑此类转换。

     

此设置对解码没有影响。

(强调我的)