gpt4 book ai didi

perl - 如何使用 Moose 从属性的元对象创建值实例?

转载 作者:行者123 更新时间:2023-12-01 08:07:06 25 4
gpt4 key购买 nike

我正在开发一种序列化工具,它使用 Moose 来读写符合非标准格式的文件。现在,我决定如何根据类中对象的默认值加载下一个项目,但这有其自身的缺点。相反,我希望能够使用属性元类中的信息来生成正确类型的新值。我怀疑有一种方法可以确定“isa”限制是什么并从中派生生成器,但我在 Moose::Meta::Attribute 或 Class::MOP::Attribute 中没有看到可以帮助我的特定方法。

这里还有一个例子。假设我有以下类(class):

package Example;
use Moose;

use My::Trait::Order;
use My::Class;

with 'My::Role::Load', 'My::Role::Save';

has 'foo' => (
traits => [ 'Order' ],
isa => 'Num',
is => 'rw',
default => 0,
order => 1,
);

has 'bar' => (
traits => [ 'Order' ],
isa => 'ArrayRef[Str]',
is => 'rw',
default => sub { [ map { "" } 1..8 ] }
order => 2,
);

has 'baz' => (
traits => [ 'Order' ],
isa => 'Custom::Class',
is => 'rw',
default => sub { Custom::Class->new() },
order => 3,
);

__PACKAGE__->meta->make_immutable;
1;

(进一步说明:My::Role::LoadMy::Role::Save 实现了此文件类型的序列化角色。它们遍历它们所附加的类的属性,并查看属性类以获得序列化顺序。 )

My::Role::Load角色,我可以遍历类的元对象,查看我可用的所有属性,并仅选择具有我的 Order 特征的属性:

package My::Role::Load;
use Moose;

...

sub load {
my ($self, $path) = @_;

foreach my $attribute ( $self->meta->get_all_attributes ) {
if (does_role($attribute, 'My::Trait::Order') ) {
$self->load_attribute($attribute) # do the loading
}
}
}

现在,我需要知道 isa元属性表示的属性。现在,我通过获取它的一个实例来测试它,并用类似这样的东西来测试它:

use 5.010_001; # need smartmatch fix.
...
sub load_attribute {
my ($self, $attribute, $fh) = @_;
my $value = $attribute->get_value($self); # <-- ERROR PRONE PROBLEM HERE!
if (ref($value) && ! blessed($value)) { # get the arrayref types.
given (ref($value)) {
when('ARRAY') {
$self->load_array($attribute);
}
when('HASH') {
$self->load_hash($attribute);
}
default {
confess "unable to serialize ref of type '$_'";
}
}
}
else {
when (\&blessed) {
confess "don't know how to load it if it doesn't 'load'."
if ! $_->can('load');
$_->load();
}
default {
$attribute->set_value($self, <$fh>);
}
}
}

但是,正如您在 # <-- ERROR PRONE PROBLEM HERE! 中看到的那样,这整个过程依赖于属性中有一个值开始!如果该值为 undef,我没有指示要加载什么。我想更换 $attribute->get_value($self)有一种方法来获取有关需要加载的值类型的信息。我的问题是我为 Class::MOP::Attribute 链接到上面的文档和 Moose::Meta::Attribute似乎没有任何方法可以获取属性应该获取的对象类型。

属性的类型信息基本上就是我想要得到的。

(请注意 future 的读者:这里的答案让我开始了,但它本身并不是最终的解决方案。你必须深入研究 Moose::Meta::TypeConstraint 类才能真正完成我在这里寻找的事情。)

最佳答案

不确定我是否遵循您的要求,也许强制转换可以满足您的要求?

但是要获取属性isa:

{
package Foo;
use Moose;

has 'bar' => ( isa => 'Str', is => 'rw' );
}


my $foo = Foo->new;

say $foo->meta->get_attribute('bar')->type_constraint; # => 'Str'

/I3az/

关于perl - 如何使用 Moose 从属性的元对象创建值实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1981631/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com