我在文件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;
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() } }; }
如果你必须下降一个结构,它会得到更多的毛发.
基础很简单所以这里
my $object = bless( JSON->new->decode( $json_string ),'ClassIWant' );
我主要介绍的部分,阻止你简单地将一个保佑的对象序列化成JSON.
反序列化的基础是简单的,就像序列化的基础是简单的 – 一旦你知道诀窍.没有错误的方式,只需要找到你需要的东西,并祝福它进入正确的课程.
如果你想要将代码与对象相结合,那么你会知道应该得到什么,祝福得到什么.如果你想要完全解耦的代码,这在Perl中并不比JavaScript本身更难或更容易.
你将不得不在JSON中序列化一个标记.如果我需要这样的东西,我会在一个祝福的对象中插入一个“__CLASS__”字段.当反序列化时,我将通过结构下降,祝福这样的一切:
bless( $ref,delete $ref->{__CLASS__} );
但是正如我所说,Perl并不容易或者更难,因为JSON对所有语言都是同样的挑战.
正如Schwern在他的评论中所提出的,YAML对于序列化和反序列化对象而言更好,因为它具有符号. JSON给出关联数组或数组.