2010-07-20 4 views
6

Je délègue actuellement la méthode du générateur à tous les objets qui étendent l'une de mes classes de base. Le problème auquel je suis confronté est que j'ai besoin que tous les objets lisent un attribut de lui-même ou soient passés dans une valeur. Est-ce actuellement possible ou est-ce que je vais devoir le faire d'une autre manière?Argument du sous-programme générateur dans un objet moose

+2

Je vais avoir du mal à comprendre exactement ce que vous essayez d'atteindre, d'expliquer peut-être du point de vue du consommateur? –

Répondre

12

Vous ne pouvez pas passer d'arguments aux méthodes de génération d'attributs. Ils sont appelés automatiquement par les internes de Moose et ne transmettent qu'un seul argument, la référence d'objet elle-même. Le générateur doit être en mesure de renvoyer sa valeur en fonction de ce qu'il voit dans $self ou toute autre chose dans l'environnement auquel il a accès.

Quel genre d'arguments voudriez-vous transmettre au constructeur? Pouvez-vous plutôt transmettre ces valeurs au constructeur d'objet et les stocker dans d'autres attributs?

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

Notez également que si vous avez des attributs qui sont construits en fonction de d'autres valeurs d'attribut, vous devez les définir comme lazy, sinon les constructeurs/défaut fonctionneront immédiatement sur la construction de l'objet, et dans un ordre indéfini. Les placer paresseux retardera leur définition jusqu'à ce qu'ils soient d'abord nécessaires.

+1

Je devais juste mettre paresseux et tout s'est parfaitement déroulé. Dans mon test d'origine, je n'avais pas cet ensemble, donc je ne pouvais pas voir les autres attributs dans ma méthode de construction. Merci! – lespea

+0

@lespea: doux! heureux d'entendre tout cela a fonctionné pour vous! :) – Ether

0

Vous pouvez faire quelque chose comme ceci:

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

sub pre_builder { 
    _builder(@_, 'your_arg'); 
} 
Questions connexes