Как я могу назначить много атрибутов Moose одновременно? - PullRequest
6 голосов
/ 11 января 2010

Я постепенно запускаю 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;

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

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

Спасибо

Ответы [ 3 ]

11 голосов
/ 11 января 2010

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

use List::MoreUtils qw/ zip /;

my $object = My::Record->new(
  zip @field_names,
      @{[ split /\|/, get_line_from_file ]}
);
7 голосов
/ 11 января 2010

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

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

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

3 голосов
/ 11 января 2010

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

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);
}
...