2010-01-11 7 views
6

Ich bin nach und nach Moose-ifying etwas Code, der Zeilen von einem Rohr getrennt liest, spaltet jede und weist sie zu einem Hash mit einem Hash-Slice hinzu.Wie kann ich viele Moose-Attribute gleichzeitig zuweisen?

Ich habe den Hash in eine Moose-Klasse umgewandelt, aber jetzt habe ich keine Ahnung, wie ich die Felder aus der Datei schnell den Attributen der Klasse zuordnen kann (wenn überhaupt).

Ich weiß, ich kann ganz einfach nur tun:

my $line = get_line_from_file; 
my @fields = split /\|/, $line; 
my $record = My::Record->new; 
$record->attr1($fields[0]); 
... 

aber ich habe gehofft, für einen schnellen einzeiler der Attribute alle in einem Rutsch zu vergeben, etwas ähnlich:

my $line = get_line_from_file; 
my %records; 
@records{@field_names} = split /\|/, $line; 

I habe über Zwang gelesen, aber von dem, was ich sagen kann, ist es nicht das, wonach ich suche.

Ist es möglich?

Dank

Antwort

7

Ich glaube, Sie mit dem Hash-Slice-Ansatz auf dem richtigen Weg sind. Ich würde so etwas wie:

my %fields; 
@fields{@field_names} = split m{\|}, $line; 
my $record = My::Record->new(%fields); 

Sie könnten in der Lage sein, mit einer knorrigen map Lösung zu entwickeln, um die gleiche Sache zu erreichen, aber ich würde hier auf der Seite der Lesbarkeit irrt.

my $line = get_line_from_file; 
my %records; 
@records{@field_names} = split /\|/, $line; 
my $object = My::Record->new(%records); 

oder wenn das Objekt bereits erstellt, und Sie möchten einige neue Felder hinzuzufügen:

+2

Wenn 2 der Attribute Arrays sind (Semikolon, das in der Datei begrenzt ist), wenn Coerce verwendet werden kann? – Sparkles

+2

Ja, Sie können Zwang in diesem Fall verwenden. Sie würden ein 'Str' zu einem' Array' zwingen, indem Sie eine Zwangsfunktion wie 'sub {return [split /; /, $ _ [0]}' ' – friedo

3

Wenn das Objekt noch nicht aufgebaut ist, können Sie einfach alle Schlüssel und Werte in den Konstruktor übergeben

my $line = get_line_from_file; 
my %records; 
@records{@field_names} = split /\|/, $line; 
while (my ($key, $value) = each(%records) 
{ 
    $object->$key($value); 

    # or if you use different names for the setters than the "default": 
    $object->set_value($key, $value); 
} 
11

Geben der Attribute an den Konstruktor zip vom List::MoreUtils Modul:

use List::MoreUtils qw/ zip /; 

my $object = My::Record->new(
    zip @field_names, 
     @{[ split /\|/, get_line_from_file ]} 
); 
+0

+1 für' zip' verwenden, sehr nett. – friedo

Verwandte Themen