0

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?

Mat
  • 202,337
  • 40
  • 393
  • 406
simon_
  • 43
  • 5

1 Answers1

1

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 )
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Thanks, but i'm working with a hash ($self->hash, which does some magic to construxt a has from $self->obj), and afaik i can't delegate to keys in a hash? – simon_ Jan 29 '12 at 09:57
  • @simon_, You say it's a hash, but then you continue to call it `$obj` and say the hash is actually constructed from it. Which one is it? If `$obj` is an object, use delegates. Place any "magic" you need in the delegate. (e.g. `val1 => sub { my $self = shift; my $obj = $self->obj; ... }`) – ikegami Jan 29 '12 at 10:04
  • Well, the $obj I pass to the constructor is an object. The hash with the values I want to use for the FOOBAR attributes is generated from $obj with a custom method 'make_hash'. I don't really se how this was unclear.. – simon_ Jan 29 '12 at 10:39
  • thanks for the updated code. i guess i can do something like this! – simon_ Jan 29 '12 at 10:40
  • actually... The suggested delegate approach is going to be inefficient because i would have to mangle/decode/etc $self->obj in ever sub ref in 'handles' – simon_ Jan 29 '12 at 11:00