2010-07-20 15 views
6

Obecnie deleguję metodę konstruktora do wszystkich obiektów, które rozszerzają jedną z moich klas bazowych. Problem, z którym się borykam, polega na tym, że potrzebuję wszystkich obiektów, aby albo odczytały jakiś atrybut lub przekazały wartość.Argument dla podprocedury konstruktora w obiekcie łosia

# 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? 
} 

Czy jest to obecnie możliwe, czy też będę musiał to zrobić w inny sposób?

+2

mam problemy ze zrozumieniem dokładnie co to jest starasz się osiągnąć, może to wyjaśnić z punktu widzenia konsumenta? –

Odpowiedz

12

Nie można przekazywać argumentów w celu przypisania metod kompilacji. Są one wywoływane automatycznie przez elementy wewnętrzne Moose i przekazują tylko jeden argument - sam obiekt odniesienia. Budowniczy musi być w stanie zwrócić swoją wartość w oparciu o to, co widzi w $self, lub cokolwiek innego w środowisku, do którego ma dostęp.

Jakiego rodzaju argumenty chciałbyś przekazać twórcy? Czy zamiast tego możesz przekazać te wartości do konstruktora obiektów i przechowywać je w innych atrybutach?

# 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'); 

Należy również pamiętać, że jeśli masz atrybutów, które są budowane w oparciu off innych wartości atrybutów, należy je określić jako lazy, inaczej budowniczych/domyślnie będzie działać bezpośrednio na konstrukcji obiektu, w nieokreślonym celu. Ustawienie ich leniwych opóźni ich definicję, dopóki nie będą potrzebne.

+1

Po prostu musiałem ustawić leniwych i wszystko działało idealnie. W moich oryginalnych testach nie miałem tego zestawu, więc nie widziałem innych atrybutów w mojej metodzie budowania. Dzięki! – lespea

+0

@lespea: słodka! Cieszę się, że to wszystko się udało! :) – Ether

0

można zrobić coś takiego:

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

sub pre_builder { 
    _builder(@_, 'your_arg'); 
} 
Powiązane problemy