2014-02-28 16 views
5

Was ist der typische Ansatz für die benutzerdefinierte Initialisierung bestimmter Attribute bei der Verwendung von Moose?Moose-Attribut-Initialisierung

Zum Beispiel: Angenommen ich nehme zwei Daten im String-Format als Eingabe in meine Klasse:

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

Diese Daten als Strings kommen, aber ich brauche sie in einem bestimmten Datumsformat (ISO8601) formatieren, ohne Moose würde ich sie einfach in new() initialisieren, aber ich bin unsicher mit Elch.

Es scheint, dass die praktikablen Optionen aus dem Lesen der Dokumente sind in BUILDARGS, BUILD oder mit Zwang. Welche davon wäre am besten geeignet, da ich eine Funktion habe, die ein Datum nehmen und es richtig formatiert zurückgeben kann?

Antwort

5

BUILD wird nach dem Konstruktor aufgerufen, was es praktisch macht, den Status zu überprüfen, aber nicht unbedingt nützlich, um eingehende Argumente zu formatieren.

BUILDARGS können Sie eingehende Argumente ändern, bevor der Konstruktor aufgerufen wird, die es besser für diesen Fall passt. Ihr Attribut ist schreibgeschützt, das könnte also funktionieren.

Aber ... wenn Sie hungrig nach statischer Typisierung sind, warum sollten Sie aufhören, nachdem Sie versprochen haben, "das ist ein String"? Wenn Sie eine subtype für ISO8601-Strings erstellen, können Sie "Dies ist eine Zeichenfolge und es hat X-Format". Noch besser, Sie tun das auf eine Art und Weise, die sofort und trivial auf andere Attribute übertragbar ist.

Ich bezweifle, eher die Regex unten für Sie arbeiten, aber ich hoffe, es wird die Nummer auf:

#define the type 
subtype 'iso8601', 
    as 'Str', 
    where { /\d{4}-\d{2}-\d{2}/ }, 
    message { "Not a valid ISO8601 string ($_)" }; 

#provide a coercion 
coerce 'iso8601', 
    from 'Str', 
    via { _format_as_iso8601 $_ }; 

#tell moose to coerce the value 
has startdate => (is => 'ro', isa => 'iso8601', required => 1, coerce => 1); 
+0

Danke, das ist nur die Art der Lösung, die ich bestanden hatte gehofft. –

+3

Meine Typen :: XSD verfügt über eine integrierte Einschränkung des Datums. Hier ist [ein Beispiel aus einer Zeichenkette] (https://gist.github.com/tobyink/9280334). Der Typ ist parametrisierbar, so dass Sie Typabhängigkeiten wie 'Date [minInclusive => '1970-01-01']' verwenden können. – tobyink

+0

@tobyink Das ist wirklich cool, ich werde definitiv diesen Weg gehen, es scheint der flexibelste zu sein, ohne dass ich etwas aufgebaut habe. –