Frage

Ich arbeite an einem Serialisierungsfunktion Moos mit einer Datei, die Konformität mit einem Nicht-Standard-Format lesen und zu schreiben. Gerade jetzt, ich bestimmen, wie das nächste Element für die Objekte in der Klasse auf den Standardwerten basiert laden, aber das hat seine eigenen Nachteile. Stattdessen würde Ich mag Informationen im Attribute Meta-Klasse in der Lage sein zu verwenden, um einen neuen Wert des richtigen Typs zu erzeugen. Ich vermute, dass es einen Weg gibt, um zu bestimmen, was die ‚isa‘ Beschränkung ist und leiten einen Generator von ihm, aber ich sah keine besonderen Methoden in Moose :: Meta :: Attribut oder Klasse :: MOP :: Attribut, das mir helfen könnte.

Hier ist ein bisschen weiter von einem Beispiel. Lassen Sie uns sagen, ich habe die folgende Klasse:

package Example;
use Moose;

use My::Trait::Order;
use My::Class;

with 'My::Role::Load', 'My::Role::Save';

has 'foo' => (
    traits => [ 'Order' ],
    isa => 'Num',
    is => 'rw',
    default => 0,
    order => 1,
);

has 'bar' => (
    traits => [ 'Order' ],
    isa => 'ArrayRef[Str]',
    is => 'rw',
    default => sub { [ map { "" } 1..8 ] }
    order => 2,
);

has 'baz' => (
    traits => [ 'Order' ],
    isa => 'Custom::Class',
    is => 'rw',
    default => sub { Custom::Class->new() },
    order => 3,
);

__PACKAGE__->meta->make_immutable;
1;

(Weitere Erläuterungen:.. My::Role::Load und My::Role::Save die Serialisierung Rollen für diesen Dateityp implementieren Sie Iterierte über die Attribute der Klasse sie gebunden sind, und Blick auf die Attributklassen für einen Auftrag zur Serialisierung in)

In der My::Role::Load Rolle kann ich das Meta-Objekt für die Klasse iterieren, um alle auf der Suche die mir zur Verfügung stehenden Attribute und Kommissionierung nur diejenigen, die meine Bestellung Merkmal haben:

package My::Role::Load;
use Moose;    

...

sub load {
    my ($self, $path) = @_;

    foreach my $attribute ( $self->meta->get_all_attributes ) {
        if (does_role($attribute, 'My::Trait::Order') ) {
            $self->load_attribute($attribute) # do the loading
        }
    }
}

Nun, ich brauche das isa des Attributs zu wissen, dass das Meta-Attribut darstellt. Gerade jetzt, ich Test, dass durch eine Instanz davon bekommen, und es mit etwas zu testen, die Art ist von wie folgt aus:

use 5.010_001; # need smartmatch fix.
...
sub load_attribute {
    my ($self, $attribute, $fh) = @_;
    my $value = $attribute->get_value($self); # <-- ERROR PRONE PROBLEM HERE!
    if (ref($value) && ! blessed($value)) { # get the arrayref types.
        given (ref($value)) {
            when('ARRAY') { 
                $self->load_array($attribute);
            }
            when('HASH') {
                $self->load_hash($attribute);
            }
            default {
                confess "unable to serialize ref of type '$_'";
            }
        }
    }
    else {
        when (\&blessed) {
            confess "don't know how to load it if it doesn't 'load'."
                if ! $_->can('load');
            $_->load();
        }
        default {
            $attribute->set_value($self, <$fh>);
        }
    }
}

Aber, wie Sie bei # <-- ERROR PRONE PROBLEM HERE! sehen können, dieser ganze Prozess stützt sich auf einen Wert in dem Attribute ist zu beginnen! Wenn der Wert undef ist, habe ich keinen Hinweis auf was zu laden. Ich mag die $attribute->get_value($self) mit einer Art und Weise ersetzen, Informationen über die Art von Wert zu erhalten, der anstelle geladen werden muss. Mein Problem ist, dass die docs ich oben für die Class::MOP::Attribute verknüpft und die Moose::Meta::Attribute scheint keine Möglichkeit zu haben an der Art des Objekts bekommt, dass das Attribut soll erhalten.

Die Typinformationen für ein Attribut ist im Grunde, was ich versuche zu bekommen.

(Hinweis auf künftige Leser:.. Die Antwort hier bekam begann ich, aber nicht die endgültige Lösung in sich selbst Sie werden in die Moose::Meta::TypeConstraint Klassen graben müssen, um tatsächlich zu tun, was denn hier suche ich)

War es hilfreich?

Lösung

Nicht sicher folgen ich, was Sie nach und vielleicht Nötigungen könnte das tun, was Sie wollen?

Allerdings bekommen die Attribute isa :

{
    package Foo;
    use Moose;

    has 'bar' => ( isa => 'Str', is => 'rw' );
}


my $foo = Foo->new;

say $foo->meta->get_attribute('bar')->type_constraint;   # => 'Str'

/ I3az /

Andere Tipps

Aus Neugier, warum nicht nutzen / erweitern MooseX :: Lagerung ? Es tut Serialisierung und hat für etwa zweieinhalb Jahre. Am allerwenigsten MooseX :: Speicher werden Sie durch zeigt helfen, wie eine (gut getestet und Produktion bereit) Serialisierung Motor für Moose geschrieben wird.

Ich bin nicht ganz sicher, verstehe ich (vielleicht können Sie einige Pseudo-Code enthalten, der zeigt, was Sie suchen), aber es klingt wie Sie möglicherweise das Verhalten bekommen könnten Sie durch die Definition ein neues Attribut Merkmal wollen: richten Sie Attribut so dass eine Reihe von Methoden für die Klasse Delegierter des Objekts Attribut (isa => 'MySerializer', handles => [ qw(methods) ]).

Sie könnten möglicherweise müssen auch Unterklasse Moose :: Meta :: Class (oder besser gesagt, eine Rolle, um es hinzuzufügen), die das Verhalten von add_attribute() erweitert.

Edit: Wenn Sie an der Quelle suchen Moose :: Meta :: Attribut (speziell die _process_options Methode), werden Sie sehen, dass die isa Option von Moose :: Util :: TypeConstraints den tatsächlichen Typ zurückzukehren, in dem type_constraint Feld in dem Objekt gespeichert werden. Dies wird ein Moose :: Meta :: TypeConstraint :: Class Objekt, mit dem Sie Anrufe wie is_a_type_of() gegen machen können.

Dieses Feld ist über die type_constraint Methode in Moosen :: Meta :: Attribut verfügbar. Siehe Moose :: Meta :: TypeConstraint für alle Schnittstellen zur Verfügung Sie eine Attribute des Typs zu überprüfen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top