2010-07-20 19 views
6

Actualmente, estoy delegando el método del generador en todos los objetos que extienden una de mis clases base. El problema que estoy enfrentando es que necesito que todos los objetos lean un atributo de sí mismos o se pasen en un valor.Argumento para la subrutina del constructor en un objeto alose

# In Role: 
has 'const_string' => (
    isa  => 'Str', 
    is  => 'ro', 
    default => 'test', 
); 

has 'attr' => (
    isa  => 'Str', 
    is  => 'ro', 
    builder => '_builder', 
); 

requires '_builder'; 


# In extending object - desired 1 
sub _builder { 
    my ($self) = shift; 
    # $self contains $self->const_string 
} 

# In extending object - desired 2 
sub _builder { 
    my ($arg1, $arg2) = @_; 
    # $args can be passed somehow? 
} 

¿Es esta actualmente posible o voy a tener que hacerlo de otra manera?

+2

estoy teniendo problemas para entender exactamente qué es lo que estamos tratando de lograr, quizás explicarlo desde el punto de vista del consumidor? –

Respuesta

12

No puede pasar argumentos a los métodos de creación de atributos. Son llamados automáticamente por los internos de Moose, y pasan solo un argumento: la referencia del objeto en sí. El constructor debe poder devolver su valor en función de lo que ve en $self, o cualquier otra cosa en el entorno al que tiene acceso.

¿Qué tipo de argumentos le gustaría pasar al constructor? ¿Puede pasar estos valores al constructor del objeto y almacenarlos en otros atributos?

# in object #2: 
has other_attr_a => (
    is => 'ro', isa => 'Str', 
); 
has other_attr_b => (
    is => 'ro', isa => 'Str', 
); 

sub _builder 
{ 
    my $self = shift; 
    # calculates something based on other_attr_a and other_attr_b 
} 

# object #2 is constructed as: 
my $obj = Class2->new(other_attr_a => 'value', other_attr_b => 'value'); 

También tenga en cuenta que si tiene atributos que se construyen con sede fuera de otros valores de atributos, debe definirlos como lazy, de lo contrario los constructores/por defecto se ejecutará inmediatamente después de la construcción de objetos, y en un orden definido. Ponerlos perezosos retrasará su definición hasta que se necesiten por primera vez.

+1

Solo necesitaba establecer lazy y todo funcionó a la perfección. En mi prueba original no tenía ese conjunto, así que no pude ver los otros atributos en mi método de compilación. ¡Gracias! – lespea

+0

@lespea: ¡dulce! ¡Me alegra oír que todo salió bien para ti! :) – Ether

0

Usted puede hacer algo como esto:

has 'attr' => (
isa  => 'Str', 
is  => 'ro', 
builder => '_pre_builder', 
); 

sub pre_builder { 
    _builder(@_, 'your_arg'); 
} 
Cuestiones relacionadas