如何使用 MooseX::Storage 使用自定义 init_arg 序列化 [required] 属性?
我正在尝试使用自定义 init_arg 向具有所需属性的 Moose 类添加序列化(在属性名称前添加破折号以确保 API 一致性),这似乎会导致解包失败。我在下面设置了一个测试用例来说明我的观点。
use strict;
use warnings;
package MyClass1;
use Moose;
use MooseX::Storage;
use namespace::autoclean;
with Storage;
has 'my_attr' => (
is => 'ro',
isa => 'Str',
required => 1,
);
__PACKAGE__->meta->make_immutable;
package MyClass2;
use Moose;
use MooseX::Storage;
use namespace::autoclean;
with Storage;
has 'my_attr' => (
is => 'ro',
isa => 'Str',
required => 1,
init_arg => '-my_attr',
);
__PACKAGE__->meta->make_immutable;
package main;
my $inst1 = MyClass1->new(my_attr => 'The String');
my $packed1 = $inst1->pack;
my $unpacked1 = MyClass1->unpack($packed1); # this works
my $inst2 = MyClass2->new(-my_attr => 'The String');
my $packed2 = $inst2->pack;
my $unpacked2 = MyClass2->unpack($packed2); # this fails with a ...
# ... Attribute (my_attr) is required at ...
更新:进一步调查表明问题在于打包时未考虑 init_arg。因此,即使使用自定义 init_arg 的非必需属性在解包后也无法正确恢复。请参阅此附加测试用例:
package MyClass3;
with Storage;
has 'my_attr' => (
is => 'ro',
isa => 'Str',
init_arg => '-my_attr',
);
# in main...
my $inst3 = MyClass3->new(-my_attr => 'The String');
my $packed3 = $inst3->pack;
my $unpacked3 = MyClass3->unpack($packed3); # this seems to work ...
say $unpacked3->my_attr; # ... but my_attr stays undef
非常感谢您的帮助, 丹尼斯
I'm trying to add serialization to a Moose class that has required attributes using custom init_arg's (to prefix the attribute name with a dash for API consistency) and it seems that this causes unpacking to fail. I've setup a test case below to illustrate my point.
use strict;
use warnings;
package MyClass1;
use Moose;
use MooseX::Storage;
use namespace::autoclean;
with Storage;
has 'my_attr' => (
is => 'ro',
isa => 'Str',
required => 1,
);
__PACKAGE__->meta->make_immutable;
package MyClass2;
use Moose;
use MooseX::Storage;
use namespace::autoclean;
with Storage;
has 'my_attr' => (
is => 'ro',
isa => 'Str',
required => 1,
init_arg => '-my_attr',
);
__PACKAGE__->meta->make_immutable;
package main;
my $inst1 = MyClass1->new(my_attr => 'The String');
my $packed1 = $inst1->pack;
my $unpacked1 = MyClass1->unpack($packed1); # this works
my $inst2 = MyClass2->new(-my_attr => 'The String');
my $packed2 = $inst2->pack;
my $unpacked2 = MyClass2->unpack($packed2); # this fails with a ...
# ... Attribute (my_attr) is required at ...
Update: further investigation indicates that the issue is that init_arg is not taken into account when packing. Hence, even a non-required attribute using a custom init_arg is not correctly restored after unpacking. See this additional test case:
package MyClass3;
with Storage;
has 'my_attr' => (
is => 'ro',
isa => 'Str',
init_arg => '-my_attr',
);
# in main...
my $inst3 = MyClass3->new(-my_attr => 'The String');
my $packed3 = $inst3->pack;
my $unpacked3 = MyClass3->unpack($packed3); # this seems to work ...
say $unpacked3->my_attr; # ... but my_attr stays undef
Thanks a lot for your help,
Denis
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经为上个月报告的问题编写了一个补丁。
我还添加了一个基本测试文件来检查它是否按预期工作。当前分布 (0.29) 的所有其他测试(甚至是可选的)仍然通过。但不确定对性能的影响...希望这会有所帮助(这至少对我有帮助:-)
Denis
PS:我也在 rt.cpan.org 上提交了它。
补丁如下:
测试文件在那里(t/080_basic_initarg.t):
I've written a patch for the issue I reported last month.
I've also added a basic test file to check it works as expected. All other tests (even optional) of the current distribution (0.29) still pass. Not sure about the impact on performance though... Hope this helps (this helps me at least :-)
Denis
PS: I submit it as well on rt.cpan.org.
The patch is as is:
The test file is there (t/080_basic_initarg.t):