Re: chained accessors

[email protected] (Stevan Little)
Newsgroups perl.moose
Message-ID <[email protected]>
Carl,

On Nov 21, 2006, at 4:27 AM, Carl Franks wrote:
> Can anyone give me any pointers to how I might create "chained"
> accessors which return $self when called as a setter.
> If I do:
> has( foo => ( is => 'rw' ) );
> I've found using the debugger, that $x->foo('y') calls
> Moose::Meta::Method::Accessor::generate_accessor_method()
> But I can't figure out how to wrap that (and whether that's the  
> right approach).

Wrapping is not the right approach, subclassing is. This is pretty  
much what you will need to do (this code is untested though).

package Foo::Chained::Attribute;
use Moose;

extends 'Moose::Meta::Attribute';

sub accessor_metaclass { 'Foo::Meta::Method::Accessor::Chained' }

package Foo::Meta::Method::Accessor::Chained;
use Moose;

extends 'Moose::Meta::Method::Accessor';

sub generate_writer_method {
     my $self = shift;
     my $attr = $self->associated_attribute;
     return sub {
         my ($instance, $value) = @_;
         $attr->set_value($instance, $value);
         $instance;
     }
}

sub generate_accessor_method {
     my $self = shift;
     my $attr = $self->associated_attribute;
     return sub {
         my $instance = shift;
         if (@_) {
             $attr->set_value($instance, $value);
             $instance;
         }
         $attr->get_value($instance, $value);
     }
}

Then at this point, you should be able to do this:

> package Foo;
> use Moose;
> has 'foo' => (is => 'rw', 'metaclass' => 'Foo::Chained::Attribute');

The only issue here is going to be performance. The set_value and  
get_value methods on the attribute metaclass are not very fast (they  
do too much runtime calculation), and normally we inline and eval the  
accessor methods. However the inlining code is not currently suited  
to wrapping/altering in this way. If you are so inclined, I would be  
happy to give you a commit-bit and you can refactor the inlining code  
to your needs.

- Stevan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.