我一直在玩这个代码:
package Foo;
use Moose;
package main;
my $PACKAGE = "Foo";
{
no strict 'refs';
my $has = *{"${PACKAGE}::has"}{CODE};
my $with = *{"${PACKAGE}::with"}{CODE};
# Add a instance member to class $PACKAGE
$has->("bar", is => "rw", required => 1);
# Add a role to class $PACKAGE
$with->("some::role");
}
# Create an instance of $PACKAGE:
$PACKAGE->new(); # error: attribute 'bar' is required means we were successful
这允许我在运行时创建Moose类,即将实例成员添加到类,添加角色等。
我的问题是:如何将Moose导入包$PACKAGE
?
我知道我可以使用eval执行此操作:eval "package $PACKAGE; use Moose";
但我想知道是否有Moose->import(... $PACKAGE ...)
的解决方案。
即一种不使用eval
的方法。或者是否有一种完全不同的方式在运行时创建和修改Moose类?
答案 0 :(得分:19)
您可能想要查看Moose::Meta::Class及其create
方法:
my $class = Moose::Meta::Class->create('Foo',
attributes => [attr => Moose::Meta::Attribute->new(is => 'ro'), ...],
roles => [...],
methods => {...},
superclasses => [...],
);
# Edit: Adding an attribute and method modifiers:
$class->add_attribute(otherattr => (is => 'ro'));
$class->add_around_method_modifier(methodname => sub { ... });
Moose::Meta::Class
是Class::MOP::Class的子类,所以您可能也想查看那个。通过上面的内容,您可以指定角色,超类,属性和方法,或者您可以先创建,然后通过MOP添加它们;什么都是最合适的。
对于你想要Moose类的属性,这意味着Moose::Meta::Attribute个对象。该对象的构造函数与使用has
基本相同。
答案 1 :(得分:4)
您可能想要使用Class :: MOP,例如参见https://metacpan.org/module/Moose::Manual::MOP#ALTERING-CLASSES-WITH-THE-MOP 要么 https://metacpan.org/module/Class::MOP::Class#SYNOPSIS
答案 2 :(得分:-5)
致电extends
,with
,has
,before
,after
,around
,override
和{{1}在Moose包中而不是由Moose导出的包,并将您正在创建的类的augment
对象作为附加的第一个参数传递。
meta