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

时间:2011-08-22 04:33:40

标签: 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

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

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

我知道我可以使用eval执行此操作:eval "package $PACKAGE; use Moose";但我想知道是否有Moose->import(... $PACKAGE ...)的解决方案。

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

3 个答案:

答案 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::ClassClass::MOP::Class的子类,所以您可能也想查看那个。通过上面的内容,您可以指定角色,超类,属性和方法,或者您可以先创建,然后通过MOP添加它们;什么都是最合适的。

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

答案 1 :(得分:4)

答案 2 :(得分:-5)

致电extendswithhasbeforeafteraroundoverride和{{1}在Moose包中而不是由Moose导出的包,并将您正在创建的类的augment对象作为附加的第一个参数传递。

meta