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