Done a bit of noodling about this morning and I got this. And it works....
sort of.

.perl calls the get_value method but the accessor and private value reads
don't. (I'm guessing this is what you came up against Vadim?)

Still the self deleting wrapper is a fun trick. Best I do some work now
though.

use v6.c;

role LazyAttr {
    has $.get-wrapper is rw;
}

multi sub trait_mod:<is> ( Attribute $a, :@lazy [ &builder ] ) {
    $a does LazyAttr;

    $a.set_build(
        -> |c {
            $a.get-wrapper = $a.^find_method('get_value').wrap(
                -> $self, $instance {
                    my $val = &builder( $instance );
                    $a.set_value( $instance, $val );
                    $a.get-wrapper.restore;
                    $val;
                }
            );
            Any;
        }
    );
}

class Test {

    sub build-a( $self ) { note "Build A Called"; sleep 1; 5 }
    sub build-b( $self ) { note "Build B Called"; sleep 2; 10 }

    has $.a is lazy[&build-a];
    has $.b is lazy[&build-b];
}

my $t = Test.new();

say $t.perl;

On Wed, 5 Sep 2018 at 23:45 Vadim Belman <vr...@lflat.org> wrote:

> Looking forward to see what you come up with. I do mix in a role into both
> Attribute and ClassHOW. But delving into the core didn't help to find a
> better approach than the one I finally took. Two subtle aspects are to be
> kept in mind: support for roles; and knowing the object attribute is
> belonging to.
>
> > So I have a thought for how to do lazy attributes without Proxy objects.
> It is late so I'll try and poke about at it tomorrow but I think we can
> Mixin a role to the Attribute using a trait.
> >
> > The role will track if the attribute was set to a value at build and if
> not call a block it's given when first read from. This gets round the issue
> of if we want to set it to Any.
> >
> > I *think* this will work. The stuff I've been doing with Trait::Env
> would point that way.
> >
>
> Best regards,
> Vadim Belman
>
> --
Simon Proctor
Cognoscite aliquid novum cotidie

Reply via email to