On Tue, 20 Apr 2004, Brent 'Dax' Royal-Gordon wrote: > John Williams wrote: > > 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?) > > C# does it as > ...
Interesting. Here's the Delphi version, for comparison. // the trivial attibute SomeNumber : Integer; // the virtual property // read/write can refer to either a variable or a func/proc property VirtWrite : Integer read SomeNumber write SetSomeNumber; procedure SetSomeNumber( in : Integer ); function GetSomeNumber : Integer; The big win being that one can replace the trivial attribute with a property, and the interface stays the same. The perl6 version of that would of course be class Dog { method getfoo returns Int {...}; method setfoo(Int $v) {...}; has Int $.foo will FETCH \&getfoo will STORE \&setfoo; } I'm not saying there is anything wrong with that. I completely agree with Larry that the correct interface for accessors is $x = $obj.foo = $y; I'm mainly curious if there is an even simpler way to define the implementation of the accessor than the above. The simplest possible rw accessor is method foo is rw { $.foo }; which basically just makes $.foo available to the outside. When you get more complex and need to intercept the reading and writing, it's clear that returning a Proxy object is the best way (so far proposed) to do the right thing for ($x = $obj.foo = $y) and ($obj.foo++). For convenience and to avoid being uncool-retro, one also wants to separate the accessor into read and write multi methods. multi method foo() returns Int {...}; multi method foo(Int $v) {...}; has Int $.foo will FETCH { .foo } # ignore the name conflict for now will STORE { .foo($^value) }; The declaration of the "has" variable to delegate to the above methods now becomes repetitive boilerplate code, which could be eliminated by a clever trait. It also interferes with the obvious name for a multi method reader. foo() obviously works fine (by itself) as a reader, but foo($) needs some help. Somehow foo() has to return a Proxy which delegates STOREs to foo($), and FETCHes to itself. Since foo() works fine as a read-only accessor by itself, a minimalist approach shouldn't require foo() to add a trait. foo($) needs the help so it should get the trait. So I propose (in the request-for-comments sense, not the "this should go into perl6 core" sense) that given a trivial accessor: has $.foo is rw; the minimal replacement with full read/write control would be this: multi method foo() {...}; multi method foo($v) is accessor {...}; (And the accessor trait somehow does the magic to define a new foo() which returns a Proxy which delegates to the declared foo() or foo($).) ~ John Williams