2010-11-18 2 views
2

У меня есть следующие пять лосей атрибуты:Как создать кучу атрибутов в Moose?

has ['summary_file', 'html_file', 'url1', 'url2', 'txt_file'] => (
    is  => 'rw', 
    isa  => 'Str', 
    required => 0, 
    lazy  => 1, 
    default => sub { confess "Attribute not set"; }, 
    ); 

Я хотел бы:

  1. Пусть каждый из них использует свой собственный конструктор (например, набор 'summary_file' использование _build_summary_file и т.д.)
  2. Марка значение по умолчанию confess, состояние которого (неинициализированный) было вызвано (например, "Attribute 'summary_file' not set").

Я могу выполнить вышеуказанное, написав пять отдельных has, но, возможно, есть более компактный способ?

ответ

4

Вы могли бы сделать что-то вроде следующего (новый рабочий пример после вашего «не работает» комментарий ниже):

package My::Class; 
use Moose; 
use namespace::autoclean; 

for my $attr (qw(x y)) { 
    has $attr => (
     is  => 'rw', 
     isa  => 'Str', 
     required => 0, 
     lazy  => 1, 
     builder => "_build_$attr", 
    ); 
} 

sub _build_x { rand } 
sub _build_y { rand } 

__PACKAGE__->meta->make_immutable; 

package main; 

use strict; use warnings; 

my $o = My::Class->new; 

print $o->$_, "\n" for qw(x y); 

Обратите внимание, что вы не можете указать как default и builder.

@Oesor указывает на комментарий что-то я забыл:

has ['summary_file', 'html_file', 'url1', 'url2', 'txt_file'] => (
    is   => 'rw', 
    isa  => 'Str', 
    required => 0, 
    lazy_build => 1, 
); 
+1

Или просто объявите их lazy_build, по умолчанию используется _build_ $ accessor. – Oesor

+2

@Oesor: в этом случае вы также получите публичный предикат и более четкий, что часто нежелательно. – Ether

+0

в соответствии с документом 'lazy_build' также устанавливает' required' значение true. что это значит? –

0

Если вы ищете атрибут бросить исключение в отношении доступа, когда он не имеет значения, установленного, посмотрите на MooseX::LazyRequire.

Если вы ищете, чтобы строитель выдал предупреждение, если он вызван, включите этот оператор в метод построителя ... ИЛИ оберните метод accessor/reader для этого. (Например, «before 'attribute_name' => sub { ...complain... };»)

Если вы ищете способ, чтобы указать методы строитель атрибута, используя тот же порядок именования lazy_build делает, см MooseX::AttributeShortcuts (с поддержкой „builder => 1“ как «builder => "_build_${attribute_name}"»).

Смежные вопросы