On Tue, 20 Apr 2004, Luke Palmer wrote: > John Williams writes: > > On Tue, 20 Apr 2004, Luke Palmer wrote: > > > There. Now here's the important part: in order to *use* all this, you > > > import whatever module defines it, and then say: > > > > > > class Dog { > > > method foo (?$arg) is accessor { > > > # accessor code here > > > } > > > } > > > > > > If that's not easy enough for you, well, you're probably out of luck. > > > > It would be even easier if we could put the read-accessor-code and > > write-accessor-code in different methods. > > > > class Dog { > > multi method foo { ... } > > multi method foo ($arg) is accessor { ... } > > } > > Ugh! That's what I originally suggested, and it was shot down it was. > > My first solution to your problem introduced the traits C<get> and > C<set>, allowing you to write it like this: > > class Dog { > method foo () > will get { ... } > will set { ... } > { } # usually empty > } > > I guess I bogged down that message with the implementation, so the > result may have been easy to miss.
Well, I think we've come full circle. The get/set is the same as the presumed current implementation, just with different keywords: class Dog { has $.foo will FETCH { ... } will STORE { ... } ; } I'm not saying there is anything wrong with that, but John Siracusa is asking for something different, I think. A simple accessor which looks like a method without having to play with Proxy, FETCH, STORE, etc. If it still looks like $obj.foo = 1 outside the class, that's good too. (Delphi and C# can do it; why can't we?) Getting the multi-methods foo()/foo($) to automagically act as the reader/writer for a virtual foo attibute seems like it would fulfill his requirements. foo() already works for the reader, but foo($) needs some help to make $obj.foo = 1 call $obj.foo(1). Here's a feeble attempt to do what I suggested: role accessor { has $.accessor = 1; multi sub trait_auxiliary:is( accessor $trait, &meth(Any) ) { my $class = &meth.meta.class; class $class is extended { # class methods take precedence, so install a method # in the class "is default" so it gets called first multi method $meth.meta.name () is default { return my $proxy is Proxy ( STORE => { &meth($^val) }, FETCH => { my ($reader) = grep !$_.meta.default , $class.meta.getmethods; &$reader; }, ); } } $meth does accessor; } } class Dog { multi method foo { ... } multi method foo ($arg) is accessor { ... } } my Dog $spot; $spot.foo++; ~ John Williams