如何将Perl对象转换成JSON,反之亦然

我在文件Point.pm中定义了一个Point对象,如下所示:
package Point;
sub new {
    my ($class) = @_;
    my $self = {
        _x => 0,_y => 0,};
    return bless $self => $class;
}

sub X {
    my ($self,$x) = @_;
    $self->{_x} = $x if defined $x;
    return $self->{_x};
}

sub Y {
    my ($self,$y) = @_;
    $self->{_y} = $y if defined $y;
    return $self->{_y};
}

1;

现在当我使用JSON通过以下代码将对象转换为JSON时:

use JSON;
use Point;

Point $p = new Point;
$p->X(20);
$p->Y(30);

my $json = encode_json $p;

我收到以下错误

encountered object 'Point=HASH(0x40017288)',but neither allow_blessed nor convert_blessed settings are enabled at test.pl line 28

如何使用JSON模块将JSON转换为对象?

解决方法

那么警告告诉你什么是错的. JSON不会处理有福的引用(即对象),除非你告诉它做什么:

你可以convert_blessed,你可以allow_blessed.对于allow_blessed,它说:

If $enable is false (the default),then encode will throw an exception when it encounters a blessed object.

Point是一个对象类,因此Point的一个实例是一个有福的引用,因此JSON的认值是抛出异常.

如果启用convert_blessed,它将在对象上调用TO_JSON方法.使用像Point(不包含祝福成员)的简单对象,您可以轻松地执行:

sub TO_JSON { return { %{ shift() } }; }

如果你必须下降一个结构,它会得到更多的毛发.

有人在下面的评论中说,我没有涵盖如何从JSON中获取对象.

基础很简单所以这里

my $object = bless( JSON->new->decode( $json_string ),'ClassIWant' );

我主要介绍的部分,阻止你简单地将一个保佑的对象序列化成JSON.

反序列化的基础是简单的,就像序列化的基础是简单的 – 一旦你知道诀窍.没有错误的方式,只需要找到你需要的东西,并祝福它进入正确的课程.

如果你想要将代码与对象相结合,那么你会知道应该得到什么,祝福得到什么.如果你想要完全解耦的代码,这在Perl中并不比JavaScript本身更难或更容易.

你将不得不在JSON中序列化一个标记.如果我需要这样的东西,我会在一个祝福的对象中插入一个“__CLASS__”字段.当反序列化时,我将通过结构下降,祝福这样的一切:

bless( $ref,delete $ref->{__CLASS__} );

但是正如我所说,Perl并不容易或者更难,因为JSON对所有语言都是同样的挑战.

正如Schwern在他的评论中所提出的,YAML对于序列化和反序列化对象而言更好,因为它具有符号. JSON给出关联数组或数组.

相关文章

1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(...
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据...
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,...
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了...
在实际生产环境中,常常需要从后台日志中截取报文,报文的形...
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让...