simon_
simon_

Reputation: 43

How can I construct a moose object from a hash generated from one of the attributes?

I have a couple of packages:

package FOO;
use Moose;
has 'obj' => (is=>'ro');
sub hash { 
    my $self = shift;
    return $self->make_hash($self->obj}; 
}

and another package extending FOO:

package FOOBAR;
use Moose;
extends 'FOO';
has [qw/val1 val2/] => (is => 'rw');
sub BUILD {
    my ($self) = @_;
    $self->val1($self->hash->{val1});
    $self->val2($self->hash->{val2});
}

Basically I want to do FOOBAR->new(obj=>$obj); and use a hash generated from $obj to populate the attributes specified in FOOBAR (~20 or so attributes)

Is using 'BUILD' like this a good way of solving it?

Upvotes: 0

Views: 354

Answers (1)

ikegami
ikegami

Reputation: 385897

Why? Then you end up with two copy of the data. Delegate instead.

has obj => (
   is      => 'ro',
   handles => {
      val1 => sub { my $self = shift; my $obj = $self->obj; ... },
      val2 => sub { my $self = shift; my $obj = $self->obj; ... },
   },
);

If the accessors are practically identical, you can do something like

sub make_obj_accessor {
   my ($name) = @_;
   return sub {
      my $self = shift;
      my $obj = $self->obj;
      ... $name ...
   };
}

has obj => (
   is      => 'ro',
   handles => {
      (map make_obj_accessor($_), qw(
         val1
         val2
      ))
   },
);

Of course, if you really only have a hash, all you need is

FOOBAR->new( %hash )

Upvotes: 1

Related Questions