我在文件中定义了一个Point对象,Point.pm如下所示:
Point.pm
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 如何处理 祝福的 引用(Perl对象),否则 JSON 仅处理非祝福的数据结构。
JSON
你可以convert_blessed,你可以allow_blessed。对于allow_blessed,它说:
convert_blessed
allow_blessed
如果$enable为false(默认值),则编码在遇到受祝福的对象时将引发异常。
$enable
Point 是一个对象类,因此的一个实例Point是一个有福的引用,因此for的默认设置JSON是引发异常。
Point
如果启用convert_blessed,它将TO_JSON在您的对象上调用一个方法。使用 简单的 对象Point(不包含受祝福成员的对象),您可以像执行以下操作一样轻松:
TO_JSON
sub TO_JSON { return { %{ shift() } }; }
如果你有一个下降的结构,它会得到 很多的 多毛。
以下评论中的某人说,我没有介绍如何 从 JSON中获取对象。
基础很简单。所以这里去
my $object = bless( JSON->new->decode( $json_string ), 'ClassIWant' );
我主要介绍了 阻止 您简单地将受祝福的对象序列化为JSON的部分。
反序列化的基础很简单,就像序列化的基础很简单一样-一旦知道了窍门。方式上没有错误,只有找到所需内容并将其祝福给正确的班级的任务。
如果您想将代码耦合到对象,那么您将知道必须祝福的内容以及必须祝福的内容。如果您想要完全解耦的代码,那么 在Perl中这比在JavaScript本身中更难或更容易 。
您将必须在JSON中序列化 标记 。如果我需要这样的东西,我会'__CLASS__'在祝福对象中插入一个字段。反序列化时,我将遍历结构并为所有类似的事情祝福:
'__CLASS__'
bless( $ref, delete $ref->{__CLASS__} );
但是正如我所说,在Perl中这并不容易,也很难,因为JSON对所有语言都提出了相同的挑战。
正如Schwern在顶部的评论中所建议的那样,YAML更好地用于序列化和反序列化对象,因为它具有 注释 。JSON为您提供了一个或多个关联数组。