使用 Moose,如何设置“ro”的值?属性 Trait,在运行时?

发布于 2024-10-03 07:06:35 字数 438 浏览 7 评论 0原文

我有一个属性特征,我想在其他类属性的基础上设置它。我真的想要一个属性特征的默认值,它获取类 $self 的副本,而不是属性的元。我想在我的班级中做这样的事情:

after 'BUILD' => sub {                                                     
  my $self = shift;                                                        
  $self->meta->get_attribute('id')->column_name( $self->_unique_key_name );
};  

但是,我想保留我的属性特质RO?这可能吗。我知道 MOP 允许设置类属性的值,但我不知道如何在元属性上设置属性。

I've got an Attribute Trait that I want to set on the basis of other class attributes. I realy want a default on an Attribute Trait that gets a copy of the class $self and not the meta for the attribute. I want to do something like this in my class:

after 'BUILD' => sub {                                                     
  my $self = shift;                                                        
  $self->meta->get_attribute('id')->column_name( $self->_unique_key_name );
};  

But, I want to keep my attribute trait RO? Is this possible. I know the MOP allows one to set the value of a class-attribute, but I can't figure out how to set an attribute on the meta-attribute.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光无声 2024-10-10 07:06:35

这听起来像是一个非常奇怪的设计(为什么元类需要它所描述的类的实例?)——但是您可以通过使用元类的元类轻松地做到这一点(请记住,Moose 元类是使用 MOP 引导的本身):

$self->meta->meta->get_attribute("foo")->default($some_value);

还请记住,如果默认值本身是引用,则需要将它们包装在 coderef 中: $some_value = sub { $instance };


实际上,这不起作用 - 'default' 是只读的。我建议您重新考虑您的设计,而不是在如此低的级别上摆弄 MOP - 例如,将您的“默认”存储在另一个属性中,并编写一个委托给它的默认子:

package MyApp::Meta::Attribute::Trait::Foo;

# set at runtime, when we have an instance to store here
has _default_of_foo => (
    is => 'rw', isa => 'Object',
);
has foo => (
    is => 'ro', isa => 'Object',
    lazy => 1,
    default => sub { shift->_default_of_foo },
);

This sounds like a really odd design (why would a metaclass need an instance of a class it is describing?) -- but you can do this easily enough by using the metaclass of the metaclass (remember that Moose meta classes are bootstrapped using the MOP itself):

$self->meta->meta->get_attribute("foo")->default($some_value);

Also remember that defaults need to be wrapped in a coderef if they are references themselves: $some_value = sub { $instance };


Actually, this won't work - 'default' is read only. Rather than fiddling with the MOP at such a low level, I would urge you to reconsider your design - e.g. store your 'default' in another attribute, and writing a default sub that delegated to it:

package MyApp::Meta::Attribute::Trait::Foo;

# set at runtime, when we have an instance to store here
has _default_of_foo => (
    is => 'rw', isa => 'Object',
);
has foo => (
    is => 'ro', isa => 'Object',
    lazy => 1,
    default => sub { shift->_default_of_foo },
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文