如何将 Perl 对象转换为 JSON,反之亦然
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4185482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert Perl objects into JSON and vice versa
提问by Ibrahim
I have defined a Point object in a file Point.pmas following:
我在文件中定义了一个 Point 对象,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;
Now when I use JSONto convert the object to JSON by the following code:
现在,当我使用JSON通过以下代码将对象转换为 JSON 时:
use JSON;
use Point;
Point $p = new Point;
$p->X(20);
$p->Y(30);
my $json = encode_json $p;
I get the following error:
我收到以下错误:
encountered object 'Point=HASH(0x40017288)', but neither allow_blessed nor convert_blessed settings are enabled at test.pl line 28
How do I convert to and from JSON to an object using the JSON module?
如何使用 JSON 模块在 JSON 和对象之间进行转换?
采纳答案by Axeman
The warning tells you most of what is wrong. Unless you tell JSONhow to handle blessedreferences(Perl objects), JSONhandles only un-blessed data structures.
该警告会告诉您大部分错误。除非你告诉JSON如何处理受祝福的引用(Perl 对象),否则JSON只处理不受祝福的数据结构。
You can convert_blessedand you can allow_blessed. For allow_blessed, it says:
你可以convert_blessed,你也可以allow_blessed。对于allow_blessed,它说:
If
$enableis false (the default), then encode will throw an exception when it encounters a blessed object.
如果
$enable为 false(默认值),则 encode 将在遇到受祝福的对象时抛出异常。
Pointis an object class, thus an instance of Pointis a blessed reference, and thus the default for JSONis to throw an exception.
Point是一个对象类,因此 的实例Point是一个受祝福的引用,因此默认为JSON抛出异常。
If you enable convert_blessed, it will call a TO_JSONmethod on your object. With simpleobjects like Point(ones that contain no blessed members), you can do that as easily as:
如果您启用convert_blessed,它会TO_JSON在您的对象上调用一个方法。使用简单的对象Point(不包含祝福成员的对象),您可以轻松地做到这一点:
sub TO_JSON { return { %{ shift() } }; }
If you have to descend a structure, it will get a lothairier.
如果你有一个下降的结构,它会得到很多的多毛。
Somebody in the comments below said that I didn't cover how to get objects outof JSON.
下面评论中有人说我没有介绍如何从JSON 中获取对象。
The basics are simple. So here goes
基础很简单。所以这里是
my $object = bless( JSON->new->decode( $json_string ), 'ClassIWant' );
I mainly covered the part that preventsyou from simply serializing a blessed object into JSON.
我主要介绍了阻止您简单地将祝福对象序列化为 JSON 的部分。
The basics of deserialization are simple, just like the basics of serialization are simple--once you know the trick. There is no error in the way, there is just the task of finding what you need and blessing it into the right class.
反序列化的基础很简单,就像序列化的基础很简单一样——只要你知道诀窍。方法没有错误,只是找到你需要的东西并祝福它进入正确的班级。
If you want to have code coupled to the objects, then you'll know what has to be blessed and what it will have to be blessed into. If you want totally decoupled code, this is no harder or easier in Perl than it is in JavaScript itself.
如果您想将代码与对象耦合,那么您将知道必须祝福什么以及必须祝福什么。如果你想要完全解耦的代码,这在 Perl 中并不比在 JavaScript 中更难或更容易。
You're going to have to serialize a markerin the JSON. If I need something like this, I will insert a '__CLASS__'field into the blessed objects. And when deserializing, I will descend through the structure and bless everything like this:
您将不得不在 JSON 中序列化一个标记。如果我需要这样的东西,我会'__CLASS__'在祝福对象中插入一个字段。当反序列化时,我将通过结构下降并祝福这样的一切:
bless( $ref, delete $ref->{__CLASS__} );
But as I said, this is no easier or harder in Perl, because JSON presents the same challenge to all languages.
但正如我所说,这在 Perl 中没有更容易或更难,因为 JSON 对所有语言都提出了相同的挑战。
As Schwern suggested in his comment up top, YAML is much better built for serializing and deserializing objects, because it has notationfor it. JSON gives you associative arrays or arrays.
正如 Schwern 在他的评论中所建议的那样,YAML 更适合用于序列化和反序列化对象,因为它有表示法。JSON 为您提供关联数组或数组。
回答by cjm
Did you try reading the JSON documentationon the allow_blessedand convert_blessedoptions, as suggested by the error message? That should explain how to convert a Perl object to JSON.
您是否按照错误消息的建议尝试阅读有关allow_blessed和convert_blessed选项的JSON 文档?这应该解释了如何将 Perl 对象转换为 JSON。
Going the other way is harder, as JSON isn't YAML, and wasn't designed to be deserialized into a class-based object system like Perl's. You could experiment with the filter_json_objector filter_json_single_key_objectoptions, or you could post-process the decoded JSON and create the objects yourself.
走另一条路更难,因为 JSON 不是YAML,并且不是为了反序列化为像 Perl 那样的基于类的对象系统。您可以试验filter_json_object或filter_json_single_key_object选项,或者您可以对解码的 JSON 进行后处理并自己创建对象。
回答by daxim
回答by Ether
You may find it useful to convert your classes to Mooseand use MooseX::Storageto serialize and deserialize them.
您可能会发现将类转换为Moose并使用MooseX::Storage对它们进行序列化和反序列化很有用。

