我经常使用Moose
确保我的数据具有合适的默认值,如下所示:
package Bla;
use Moose;
has eins => is => 'ro', isa => 'Int';
has zwei => is => 'ro', isa => 'Int', default => 2;
no Moose; __PACKAGE__->meta->make_immutable;
package main;
use v5.10;
use Data::Dumper;
use URI;
my $bla = Bla->new( eins => 77 );
my $bl2 = Bla->new;
print Dumper $bla, $bl2;
say join "\t", %$bla;
say join "\t", %$bl2;
my $u = URI->new( 'http://www.example.com/ws' );
$u->query_form( %$bla );
say $u;
$u->query_form( %$bl2 );
say $u;
只要这种数据容器没有任何引用成员(因此没有嵌套),您会说可以或推荐只使用
%$object
中的对象哈希表吗?如果您想获取原始数据,假设通过 URI->query_form
作为序列化的初始化程序或类似的方法?或者有没有更好的方法来实现这一点,这是 Moose 内置的?更新
看起来我一直在通过在上面的行、标题甚至标签中删除小词序列化来引导人们走错路。请注意,我对查找序列化程序不感兴趣。在我的示例中,
URI
模块是序列化器。问题是如何获取数据以提供 URI->query_form
(或我可能尝试的任何其他序列化程序)。所以我想知道是否对于给定的 Moose 对象 $object
可以通过取消引用对象引用来获取数据(键和值,或者,如果您愿意,属性名称和值),如 %$object
?只要对象不包含任何引用值(如数组引用、其他对象等)并且 - 我不确定 - Moose 赢了'不要使用实例引用来存储它自己的数据,如 __MOOSE_WHATNOT => $funky_moose_addon
.那么 Moose 可能会使用实例引用来存储它自己的一些数据,还是设计排除了这种情况?更新 2
要回答标题中的问题:
不行,不能用
%$object
获取 Moose 对象的数据,即使它不包含任何引用值,因此您将获得组成 $object
的字符串和数字的副本.这不好,因为它破坏了封装。它甚至可能导致运行时错误,因为尽管哈希是构成 Moose 对象基础的默认数据结构,但不能保证它始终是哈希,实际上它可能是其他东西。您应该使用
MooseX::Storage
相反,这将为对象提供 pack
方法。
最佳答案
正如 jira 所说,规范的方法是使用 MooseX::Storage
. %$object 的问题在于,虽然 Moose 对象实例的默认存储是祝福散列,但 Moose 没有正式 promise 始终如此。例如,MooseX::GlobRef、MooseX::NonMoose、MooseX::InsideOut 都允许替代实例结构。
像 MooseX::Storage 这样的包使用 MOP 来询问实例元对象并正确序列化数据结构。您当然可以通过爬取每个 Moose 对象后面的 Moose::Meta::Class 手动执行此操作,但老实说 MooseX::Storage
在这一点上写得很好并且非常稳定。
标准用法是:
package Class {
use Moose;
use MooseX::Storage;
with Storage();
...
}
my $o = Class->new(...)
my $u = URI->new( 'http://www.example.com/ws' );
$u->query_form( $o->pack );
关于perl - 驼鹿(Perl): Is it okay to use %$object to get the data representation of an object for serialization?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6236271/