Hi Stevan,

Thanks for the reply.  I went back and re-read the cookbook recipes.  Thanks
for the pointer.  I am still having trouble -and- am feeling kinda dumb.  I
am sure that I am doing something wrong.  I have cleaned up the code and
placed it and the output below.  For a quick recap, since this is now also
being sent to the [EMAIL PROTECTED] list, I am trying to have an attribute 
accessor
reference a slot within the same Moose object.

Despite the 'lazy' evaluation, it appears as if the attribute value is being
cached instead of being re-evaluated when the accessor is being called.

<snip>
package My::Package;
use Moose;

has 'data' => (
        is       => 'rw' ,
        isa      => 'ArrayRef',
        required => 1
);

has 'name' => (
        is      => 'ro',
        lazy    => 1 ,
        default => sub { $_[0]->data->[0]; }
);

has 'gender' => (
        is      => 'ro',
        lazy    => 1 ,
        default => sub { $_[0]->data->[1]; }
);


# ---------------------------------------------------
package main;
use Data::Dumper;

# Define the package with data ( 1,2,3 )
  my $x = My::Package->new( { data => [ qw( Fred male pebbles ) ] } );

# Test: Should get fred, it does.
    print Dumper( $x ) . "\n" ;
    print "Should say Fred. And says: " . $x->name . "\n";
    print "\n\n";

# Change data through accessor
    $x->data( [ qw( wilma female pebbles ) ] );

# Should now say wilma, it doesn't.  Still says fred.
    print Dumper( $x ) . "\n";
    print "Should say Wilma. And says: " . $x->name . "\n";
    print "\n\n";
</snip>

<snip>
$VAR1 = bless( {
                 'data' => [
                             'Fred',
                             'male',
                             'pebbles'
                           ]
               }, 'My::Package' );

Should say Fred. And says: Fred

$VAR1 = bless( {
                 'name' => 'Fred',
                 'data' => [
                             'wilma',
                             'female',
                             'pebbles'
                           ]
               }, 'My::Package' );

Should say Wilma. And says: Fred
</snip>




Thoughts?

Best,

Chris

PS.  This will probably bounce from [EMAIL PROTECTED], I can't figure out how to
subscribe,






On Tue, Mar 11, 2008 at 10:16 AM, Stevan Little <
[EMAIL PROTECTED]> wrote:

> Christopher,
>
> On Mar 11, 2008, at 12:45 PM, Christopher Brown wrote:
> > First, my compliments on Moose.  Moose is by far one of the most
> > elegant and well thought out pieces of software that I have
> > encountered in a long time.
>
> Thanks very much, that is very nice to hear :)
>
> > I am struggling with  on aspect though and am hoping that you can
> > help me out.
>
> No problem, I dont mind helping out, but you can also send questions
> like this to [email protected] as well.
>
> > I would like to install an accessor (reader really), that accesses
> > another attribute(slot) in the same object.  Something like this:
> >
> > package My::Package;
> > use Moose;
> >
> > has 'data' => ( is='rw', isa=>'ArrayRef' );
> > has 'name' => ( is=>'ro', default=> sub { my $self = shift; $self-
> > >data->[0] } );
> > has 'gender' => ( is=>'ro', default=> sub { my $self = shift; $self-
> > >data->[1] } );
> >
> > package main;
> >
> > my $object = My::Package->new( [ qw( x y z ] );
> > say $object->name; # x
> >
> > $object->data( [ qw( a b c ) ] );
> > say $object->name; #  a
> >
> ...
> >
> > First, is this possibe?  (Probably easy, but it elludes me.)
>
> Yes, what you need to do is to make the name and gender attribtues
> 'lazy', this will defer populating them so that when they access the
> data attribute it is populated. (You should also probably make the
> data attribute required too). The end result would look like this:
>
> package My::Package;
> use Moose;
>
> has 'data' => ( is='rw', isa=>'ArrayRef', required => 1 );
> has 'name' => ( is=>'ro', lazy => 1, default=> sub { my $self =
> shift; $self->data->[0] } );
> has 'gender' => ( is=>'ro', lazy => 1, default=> sub { my $self =
> shift; $self->data->[1] } );
>
> The 3rd recipe in the cookbook details how lazy work (http://
> search.cpan.org/~stevan/Moose-0.38/lib/Moose/Cookbook/Recipe3.pod<http://search.cpan.org/%7Estevan/Moose-0.38/lib/Moose/Cookbook/Recipe3.pod>
> )
> and the required option is introduced in the 4th recipe (http://
> search.cpan.org/~stevan/Moose-0.38/lib/Moose/Cookbook/Recipe4.pod<http://search.cpan.org/%7Estevan/Moose-0.38/lib/Moose/Cookbook/Recipe4.pod>
> ).
>
> Hope that helps.
>
> - Stevan
>
>
>

Reply via email to