On Thu, Jul 31, 2008 at 07:38:31PM -0700, benh wrote:
> So this was born from a conversation on IRC the other day about why
> setting an attribute returns the value that you just set to. I've been
> running with a "built in the wrong place" internal version of this but
> figured that others might find it useful. So I'm looking for some
> feedback before I toss it up on CPAN.
> 
> Tests do a better job explaining:
> http://www.develonizer.com/svn/MooseX-Setter/trunk/t/00-works.t
> 
> Code is here:
> http://www.develonizer.com/svn/MooseX-Setter/trunk/

http://www.develonizer.com/svn/MooseX-MutatorAttributes/trunk/lib/MooseX/MutatorAttributes.pm

Erm. That's -really- broken.

$self->meta->{'%!attributes'}->{$attr}

(1) You mustn't go groveling in the metaclass like that. Find the appropriate
method and call it.

(2) that's only going to work for attributes defined directly on the class.

I suspect you wanted find_attribute_by_name.

$self->$attr( $opts{$attr} );

That's gonna break when that's not what the setter's called - you need to
ask the attribute method object using get_write_method.

For serious elegance, consider exporting a $set_multi variable instead -
then instead of having to mangle every class you can do something like

use MooseX::SetMulti;

$obj->$set_multi(...)->...

I think what you want is something like

$set_multi = method (%attrs) {
  my $meta = $self->meta;
  while (my ($name, $value) = each %attrs) {
    my $attr = $meta->find_attribute_by_name($name);
    confess "No such attribute ${name} for ${self}" unless $attr;
    my $setter = $attrs->get_write_method;
    confess "No setter for attribute ${name} of ${self}" unless $attr;
    $self->$setter($value);
  }
  $self;
};

-- 
      Matt S Trout       Need help with your Catalyst or DBIx::Class project?
   Technical Director                    http://www.shadowcat.co.uk/catalyst/
 Shadowcat Systems Ltd.  Want a managed development or deployment platform?
http://chainsawblues.vox.com/            http://www.shadowcat.co.uk/servers/

Reply via email to