kob*_*ame 4 perl serialization json code-generation moose
我有一个JSON字符串,例如
use JSON::XS qw(decode_json);
say Dumper( decode_json($json) );
Run Code Online (Sandbox Code Playgroud)
将产生:
$VAR1 = {
'Fname' => 'SomeFname',
'Lname' => 'SomeLname',
'Addr' => {
'Street => 'Somestreet',
'Zip' => '00000',
},
};
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种简单的方法,如何将JSON字符串(或perl结构)"转换"为Perl/Moose对象,如:
package My;
use Moose;
has 'Fname' => (is => 'rw', isa => 'Str');
has 'Lname' => (is => 'rw', isa => 'Str');
has 'Addr' => (is => 'rw', isa => 'My::Addr');
Run Code Online (Sandbox Code Playgroud)
和
package My::Addr;
use Moose;
has 'Street' => (is => 'rw', isa => 'Str');
has 'Zip' => (is => 'rw', isa => 'Str');
Run Code Online (Sandbox Code Playgroud)
问题分为两部分:
我对Moose不是很熟练,所以需要一些链接来研究这个特殊问题.
(Moose很大 - 所以阅读CPAN中的所有内容肯定会有所帮助,但这对于一开始来说太过分了.因此,我正在寻找在现实世界中逐步学习的问题 - 如上所述).
主要问题是:
有可能从数据结构中生成Moose类definitoins(perl源)吗?存在这样的CPAN模块?
是.但是,你如何做到这在很大程度上取决于你希望实现的目标.最简单的方法是根据JSON在内存中构建属性.例如,您可以在运行时从JSON文件实例化元类对象,如下所示:
sub infer_class_from_hash {
my ($input) = @_;
# Makes for ugly class names, but does the job
my $meta = Moose::Meta::Class->create_anon_class;
for my $key (keys %$input) {
my $value = $input->{$key};
my $type;
my $coerce = 0;
# Handle nested objects in the JSON as Moose objects
if (ref $value eq 'HASH') {
my $inner_meta = infer_class_from_hash($value);
$type = $meta->name;
# We provide an automatic HASH -> Class coercion
$coerce = 1;
}
# Assume arrays are always of scalars, could be extended to handle objects
elsif (ref $value eq 'ARRAY') {
$type = 'ArrayRef',
}
# Assume anything else is string-ish
else {
$type = 'Str',
}
$meta->add_attribute($key =>
is => 'rw',
isa => $type,
coerce => $coerce,
);
}
# Create a coercion that makes instantiating from the JSON tree dead simple
use Moose::Util::TypeConstraints;
coerce $meta->name => from 'HashRef' => via { $meta->name->new($_) };
no Moose::Util::TypeConstraints;
return $meta;
}
Run Code Online (Sandbox Code Playgroud)
所有这一切甚至都没有开始进入你能做的事情.您可以应用角色,自定义基类,添加方法等.但是,这是构建Moose类的基础知识.
如果你想让一个代码生成器输出实际的Moose类作为可以构建一次然后再加载的文件,那就做你想做的事.我只是编写一个与上面类似的程序,但输出一组.pm
文件,其中包含自动生成的Moose类定义.
当我得到类层次结构时(例如,如果这里没有任何助手,我可以手动编写它们),从JSON创建(初始化)它们的实例的最简单方法是什么?
use JSON qw( from_json );
my $hash = from_json("...");
my $meta = infer_class_from_hash($hash);
my $obj = $meta->name->new($hash);
Run Code Online (Sandbox Code Playgroud)
这里的关键是我们如何使用Moose类型强制来自动将读入的JSON对象转换为Moose类实例.如果你有多个序列化方案或者想以某种其他方式使用类型约束,你可以为所有这些(在调用中create_anon_class
)设置一个基类,它提供to_json
/ from_json
方法来处理JSON输入中嵌套对象的情况.
归档时间: |
|
查看次数: |
1342 次 |
最近记录: |