программное создание класса Moose во время выполнения - PullRequest
3 голосов
/ 22 августа 2011

Я играл с этим кодом:

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 ]

19 голосов
/ 22 августа 2011

Возможно, вы захотите взглянуть на 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.

4 голосов
/ 22 августа 2011

Вы можете использовать Class :: MOP, см., Например, https://metacpan.org/module/Moose::Manual::MOP#ALTERING-CLASSES-WITH-THE-MOP или https://metacpan.org/module/Class::MOP::Class#SYNOPSIS

0 голосов
/ 22 августа 2011

Вызовите extends, with, has, before, after, around, override и augment в пакете Moose вместо пакетов, экспортированных Moose, и передайтеmeta объект класса, который вы создаете в качестве дополнительного первого аргумента.

use strict;
use warnings;
use feature qw( say );

use Moose qw( );

{ # Create MyClass on the fly.
   my $meta = Moose->init_meta( for_class => 'MyClass' );

   # Moose::with( $meta, 'MyRole' );

   Moose::has( $meta, foo => (
      is => 'ro',
   ));
}

say MyClass->new( foo => "Foo" )->foo;  # Foo
...