You could probably do this nicer as an Addtribute trait: Creator.pm ========== sub trait_mod:<is>(\attribute, :&proxy!) is export { attribute.package.^add_method(attribute.name,my method () { proxy($_) }) }
A.pm ==== use Creator; class A { has $!a is proxy( &func ); has $!b is proxy( &func ); } Didn’t test this thoroughly, but this should give you some idea. :-) Liz > On 16 Nov 2017, at 10:31, Fernando Santagata <nando.santag...@gmail.com> > wrote: > > Maybe someone might find this useful. > > In the end I concocted this kind of code. The price of simplicity at the base > program level is paid at the class level, with a specific BUILD submethod, > and with an even greater complexity at role level, where the accessors are > created dynamically with some metaprogramming. > > role Creator { > method create(::class, $method, $attribute is rw, &func) { > ::class.^add_method($method, my method (::class:) { > Proxy.new( > FETCH => { $attribute }, > STORE => -> $, $value { $attribute = &func($value) } > ) > }); > } > } > > class A does Creator { > has $!a; > has $!b; > submethod BUILD { > self.create(::A, 'a', $!a, { $^a * 2 }); > self.create(::A, 'b', $!b, { $^a * 3 }); > } > } > > my A $a .= new; > $a.a = 21; > say $a.a; # 42 > $a.b = 21; > say $a.b; # 63 > > > On Tue, Nov 14, 2017 at 7:09 PM, Elizabeth Mattijsen <l...@dijkmat.nl> wrote: > This might it then: > > class A { > has $!a; # $.a if you want to be able to assign with .new > method a() { > Proxy.new( > FETCH => { $!a }, > STORE => -> $, $value { $!a = $value * 2 } > ) > } > } > my $a = A.new; > $a.a = 77; > dd $a.a; # 154 > > > On 14 Nov 2017, at 18:51, Fernando Santagata <nando.santag...@gmail.com> > > wrote: > > > > Hi Liz, > > > > What I need is to preprocess the value before assigning it to an attribute. > > > > I would do that in Perl5/Moose, using "around", like this: > > > > package A; > > use Moose; > > > > has 'attribute' => (is => 'rw', isa => 'Str'); > > > > around [qw(attribute)] => sub { > > my ($next, $self, $val) = @_; > > return $self->$next unless $val; > > return $self->$next(preprocess $val); # Preprocess the value before the > > assignment > > } > > > > In this way I don't have to make an explicit call to the preprocessor any > > time I assign a value to that attribute, effectively removing that from the > > main program. > > > > I'm looking for a way to do that in Perl6. > > > > On Tue, Nov 14, 2017 at 6:11 PM, Elizabeth Mattijsen <l...@dijkmat.nl> > > wrote: > > > On 14 Nov 2017, at 18:06, Fernando Santagata <nando.santag...@gmail.com> > > > wrote: > > > I'm converting a program from Perl5/Moose. > > > I have several classes, each has some attributes that need to be > > > processed in the same way before being passed to other objects. > > > > > > When I was using Moose, I had some "around" methods that would > > > automatically modify the value before delivering it to those attributes, > > > so delegating the object to do the needed adjustments. > > > > > > Stripped to the bare bones, the thing that in Perl6 looks like this: > > > > > > class A { > > > has $!a; > > > > > > method a($val?) > > > { > > > if $val.defined { > > > # Modify $val in some way > > > $!a = $val; > > > } else { > > > $!a; > > > } > > > } > > > } > > > > > > my A $a .= new; > > > # $a.a = 42; # This outputs an error > > > $a.a(42); > > > say $a.a; > > > > > > Any hint how to make it work as an assignment, instead of a method call? > > > Better yet, is there a way to abstract that behavior in a role? > > > > I think you want “is rw” on a public attribute? > > > > class A { > > has $.a is rw; > > } > > my $obj = A.new; > > $obj.a = 42; > > dd $obj; > > =========== > > A $obj = A.new(a => 42) > > > > > > > > Liz > > > > > > > > -- > > Fernando Santagata > > > > -- > Fernando Santagata