I'm gradually Moose-ifying some code that reads lines from a pipe delimited, splits each and assigns adds them to a hash using a hash slice.
I've turned the hash into a Moose class but now I have no idea how to quickly assign the fields from the file to the attributes of the class (if at all).
I know I can quite easily just do:
my $line = get_line_from_file;
my @fields = split /\|/, $line;
my $record = My::Record->new;
$record->attr1($fields[0]);
...
but I was hoping for a quick one liner to assign all the attributes in one go, somewhat akin to:
my $line = get_line_from_file;
my %records;
@records{@field_names} = split /\|/, $line;
I've read about coercion but from what I can tell it's not what I'm after.
Is it possible?
Thanks
Pass the attributes to the constructor using zip
from the List::MoreUtils
module:
use List::MoreUtils qw/ zip /;
my $object = My::Record->new(
zip @field_names,
@{[ split /\|/, get_line_from_file ]}
);
I think you're on the right track with the hash slice approach. I'd do something like:
my %fields;
@fields{@field_names} = split m{\|}, $line;
my $record = My::Record->new( %fields );
You might be able to come up with a gnarly map
solution to achieve the same thing, but I'd err on the side of readability here.
If the object is not constructed yet, you can simply pass all the keys and values into the constructor:
my $line = get_line_from_file;
my %records;
@records{@field_names} = split /\|/, $line;
my $object = My::Record->new(%records);
or if the object is already created and you want to add some new fields:
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With