【发布时间】:2018-09-05 05:55:33
【问题描述】:
尝试构建一种优雅的方式来序列化 Moose 对象和嵌套的 Moose 对象。示例:
package Asset;
use Moose::Role;
has 'value' => (
isa => 'Int'
);
has 'owner' => (
isa => 'Person',
);
sub as_serializable {
...
}
package Car;
use Moose;
with 'Asset'; # role
has 'mileage' => (
isa => 'Int',
);
has 'driver' => (
isa => 'Person',
);
package House;
use Moose;
with 'Asset'; # role
has 'bathrooms' => (
isa => 'Int'
);
package Person;
use Moose;
has 'name' => (
isa => 'Str',
);
has 'favorite_assets' => (
isa => 'ArrayRef[Asset]', # and so on... and just to complicate things a bit...
lazy => 1
);
我想要的是某种序列化方式,可能是这样的:
use JSON;
my $car = Car();
return JSON::encode_json( $car->as_serializable() );
也许as_serializable() 方法包含一组参数,这些参数指定要扩展哪些属性(和嵌套属性),并且可能有一些防止循环扩展的保护措施,正如我在favorite_assets 属性中所暗示的那样。
在我开始自己动手之前,这样的东西是否已经存在?我必须相信某个地方的某个人已经面临这个确切的挑战。我查看了所有 Moose 文档并进行了一些搜索,但没有发现任何明显的东西,但我还是个新手。
用例是能够通过 http web api 快速序列化复杂的 Moose'ish 对象并使其可用,即可以从客户端 web 浏览器中运行的 JavaScript 访问。
谢谢!
【问题讨论】:
-
@simbabque,谢谢,MooseX::Storage 快到了。不幸的是,它实现了通过 Traits 选择要扩展的属性,而这个用例(web api)可能需要能够动态选择属性以避免不必要的大(并且计算成本高)输出。
-
我认为不存在开源。你可以有一个 JSON 模式并通过它来提供对象以“丢弃”你不想要的属性。所以你不是在谈论序列化以恢复整个对象。这一点很重要。序列化是不可逆的,整个对象不能反序列化(在大多数情况下)。
-
@simbabque,绝对正确——序列化并不是可逆的。 “丢弃”不需要的属性仍然意味着可能构建计算成本高的数据。我正在考虑推出我自己的,也许是开源的。非参考值将始终被构建;对于其他人,要扩展的属性选择将是作为方法参数传递的列表,例如 as_hashref( 'driver', 'owner', 'owner->favorite_assets' )。
-
我认为 JSON 模式可以工作。您的 API 具有可以将对象映射到的某些类型的消息。这样您的代码就不需要了解对象的底层结构。
标签: json perl serialization moose