2010-01-11 24 views
6

Poco a poco voy a alomizar un código que lee líneas de una tubería delimitada, divide cada una y las asigna a un hash usando una porción hash.¿Cómo puedo asignar muchos atributos de Moose al mismo tiempo?

He convertido el hash en una clase Moose pero ahora no tengo idea de cómo asignar rápidamente los campos del archivo a los atributos de la clase (si es que lo hace).

sé que puedo con bastante facilidad simplemente hacer:

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

pero yo estaba esperando una rápida un trazador de líneas para asignar todos los atributos de una sola vez, algo similar a:

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

I He leído acerca de la coacción, pero por lo que puedo decir, no es lo que busco.

¿Es posible?

Gracias

Respuesta

7

Creo que estás en el camino correcto con el enfoque rebanada de hash. Me gustaría hacer algo como:

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

Usted puede ser capaz de llegar a una solución retorcido map para lograr lo mismo, pero me gustaría errar por el lado de la legibilidad aquí.

+2

Si 2 de los atributos son matrices (punto y coma delimitado en el archivo) ¿es eso cuando se puede usar coerción? – Sparkles

+2

Sí, puede usar coerción en esa instancia. Deberías forzar un 'Str' a un' Array' usando una función de coerción como 'sub {return [split /;/$ _ [0]}' – friedo

3

Si el objeto no se construye sin embargo, sólo tiene que pasar todas las claves y valores en el constructor:

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

o si el objeto ya se ha creado y desea agregar algunos nuevos campos:

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

pasan los atributos al constructor usando zip del módulo List::MoreUtils:

use List::MoreUtils qw/ zip /; 

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

+1 para 'zip', muy agradable. – friedo

Cuestiones relacionadas