以编程方式在运行时创建Moose类

Eri*_*ikR 3 perl moose

我一直在玩这个代码:

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
Run Code Online (Sandbox Code Playgroud)

这允许我在运行时创建Moose类,即将实例成员添加到类,添加角色等.

我的问题是:如何将Moose导入包中$PACKAGE

我知道我可以用eval做到这一点:eval "package $PACKAGE; use Moose";但我想知道是否有解决方案Moose->import(... $PACKAGE ...).

即,一种不使用的方式eval.或者是否有一种完全不同的方式在运行时创建和修改Moose类?

pha*_*lon 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 { ... });
Run Code Online (Sandbox Code Playgroud)

Moose::Meta::ClassClass :: MOP :: Class的子,所以你可能也想看看那个.通过上面的内容,您可以指定角色,超类,属性和方法,或者您可以先创建,然后通过MOP添加它们; 什么最合适的.

对于你想要Moose类的属性,这意味着Moose :: Meta :: Attribute对象.该对象的构造函数与使用时基本相同has.

  • 当然它提供了它:`$ meta-> add_around_method_modifier(foo => sub {...})`.`has`,`with`等函数是糖输出,只是在MOP上调用方法.Sugar对于声明很棒,但是根据它可用或劫持它对我来说似乎不是一个好主意.MOP中的方法是记录在案并明确支持的. (2认同)
  • 另外:“superclasses”采用“extends”采用的参数,“roles”采用“with”采用的参数,元类上的“add_attribute”采用与“has”相同的参数。一旦您希望能够声明方法,您要么返回直接操作符号表,要么使用 MOP(希望是后者)。 (2认同)