2012-03-29 6 views
2

Angenommen, ich eine Klasse wie folgt will:Instanziierungsanwendung obligatorische Attribute während der Bauphase

my $r = Restraint->new(
    ball_class = 'Ball', 
    chain_class = 'Chain', 
); 

beiden Argumente sind zwingend notwendig:

package Restraint; 
use Moose; 

has ball => (
    is => 'ro', 
    does => 'Heavy', 
); 

has chain => (
    is => 'ro', 
    does => 'Lockable', 
); 

has ball_class => (
    is => 'ro', 
    isa => 'Str', 
); 

has chain_class => (
    is => 'ro', 
    isa => 'Str', 
); 

1; 

Jetzt habe ich die Klasse wie instanziiert werden soll.

Ich möchte auch beide ball_class und chain_class während der Konstruktion instanziieren und sie entsprechenden Attributen zuweisen, so dass ich schließlich z. $r->ball->lift oder $r->chain->lock usw.

Wie soll ich das tun?

Antwort

3

Markieren Sie einfach sie beide „required“ - siehe Moose :: Handbuch :: Attribute

Das ist nicht für „Ball“ alles tun wird oder „Kette“ though. Es gibt keine Verbindung.

Sie könnten Ball/Kette mit faulen Buildern einrichten, die auf Ihre Klassennamen verweisen (siehe das Moose Manual erneut).

Ich würde wahrscheinlich machen nur die gewünschten Objekte und leiten sie direkt obwohl in:

my $r = Restraint->new(
    ball => CannonBall->new(...), 
    chain => IronChain->new(...) 
); 

OK - Sie müssen nicht in Objekte übergeben wollen. In diesem Fall wollen Sie faule Builder. Markieren Sie den Ball als faul und geben Sie ihm einen Baumeister und Moose wird den Baumeister anrufen, wenn der Ball zum ersten Mal verwendet wird.

http://metacpan.org/pod/Moose

http://metacpan.org/pod/Moose::Manual::Attributes

http://metacpan.org/pod/Moose::Cookbook::Basics::Recipe3

die Zeit nehmen, die Elch-Dokumentation zu lesen - es gibt eine Menge davon, aber es ist sehr gut geschrieben und umfasst viele Funktionen. Viele Beispiele.

package Restraint; 
use Moose; 

has ball => (
    is => 'ro', 
    does => 'Heavy', 
    lazy => 1, 
    builder => '_build_ball' 
); 

has ball_class => (
    is => 'ro', 
    required => 1 
); 

sub _build_ball { 
    my $self = shift; 
    my $ball_class = $self->ball_class; 
    return $ball_class->new(); 
} 
+0

Ich habe das Handbuch gesehen, aber ich kann immer noch nicht herausfinden, wie es geht. Das Übergeben von Objekten wird für mich nicht möglich sein, da die Instanziierung nicht trivial sein wird - sie werden nicht immer nur "neue()" Objekte sein. Auch ich muss so viel wie möglich verstecken. –

+0

Vielen Dank. Ich habe RTFM, aber manchmal, wenn ich es an * eigenem * Beispiel sehe, zündet es die Glühbirne an. Und es tat es. –

+0

Jetzt scheint es mir, dass es zwei Antworten in einem gibt: der erste ist * alternativ *, der zweite ist wirklich eine Lösung für das ursprüngliche Problem. Darf ich vorschlagen, es in zwei separate Antworten hier zu teilen?(* Beide * würden eine Aufwertung verdient ;-D) –

1

BUILD für Instanziierung Verwendung während required nur für *_class Attribute Einstellung scheint zu einem gewissen Grad zu arbeiten, mit der Ausnahme, dass:

  • ich machen musste ball und chain read-write

Code:

package Restraint; 
use Moose; 

has ball => (
    is => 'rw', 
    does => 'Heavy', 
); 

has chain => (
    is => 'rw', 
    does => 'Lockable', 
); 

has ball_class => (
    is => 'ro', 
    isa => 'Str', 
    required => 1, 
); 

has chain_class => (
    is => 'ro', 
    isa => 'Str', 
    required => 1, 
); 

sub BUILD { 
    my $self = shift; 

    my $ball = $self->ball_class->new(); 
    $self->ball($ball); 
    my $chain = $self->chain_class->new(); 
    $self->chain($chain); 
} 

1; 

Es ist kein großes Opfer für jetzt, aber ich frage mich immer noch, ob es mehr richtigen Weg gibt.

+0

Ja, faule Bauarbeiter wie ich schon erwähnt habe. Ändere meine Antwort mit mehr Informationen. –

Verwandte Themen