2010-01-11 2 views
6

Я постепенно мускулирую некоторый код, который читает строки из разграниченного канала, разбивает каждый и присваивает их добавлению к хешу с использованием хэш-фрагмента.Как я могу назначить много атрибутов Moose одновременно?

Я превратил хэш в класс Moose, но теперь я понятия не имею, как быстро назначить поля из файла атрибутам класса (если вообще).

Я знаю, что могу довольно легко просто сделать:

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

, но я надеялся на быстрый один лайнер, чтобы присвоить все атрибуты в одном дыхании, несколько сродни:

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

I Я читал о принуждении, но из того, что я могу сказать, это не то, что мне нужно.

Возможно ли это?

Благодаря

ответ

7

Я думаю, что вы на правильном пути с хэш-среза подхода. Я хотел бы сделать что-то вроде:

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

Вы могли бы быть в состоянии придумать угловатый map решения для достижения то же самое, но я бы заблуждаться на стороне читаемости здесь.

+2

Если 2 атрибута - это массивы (с разделителем в пол-двоеточия в файле), то можно ли использовать принуждение? – Sparkles

+2

Да, вы можете использовать принуждение в этом случае. Вы принуждаете 'Str' к' Array', используя функцию принуждения, такую ​​как 'sub {return [split /; /, $ _ [0]}' – friedo

3

Если объект еще не построен, вы можете просто передать все ключи и значения в конструктор:

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

или если объект уже создан, и вы хотите добавить новые поля:

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

Передайте атрибуты конструктору с помощью zip из List::MoreUtils модуля:

use List::MoreUtils qw/ zip /; 

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

+1 для 'zip', очень приятно. – friedo

Смежные вопросы