On 4/19/04 7:20 PM, Larry Wall wrote: > On Mon, Apr 19, 2004 at 06:53:29PM -0400, John Siracusa wrote: > : Yeah, that's exactly what I don't want to type over and over :) > > I really don't understand what you're getting at here. First you > complain that you'd rather write an ordinary method, and then you > complain that you have to. Have I met someone lazier than me? :-)
Possibly :) Here's what I'm saying. In the first version of a class, there will probably be a lot of simple get/set attributes. It's convenient not to have to write any explicit methods for those. If I accept the default accessors that you get "for free" when a class "has $.foo is rw", then that means the users of my class can do $obj.foo = whatever in order to set the foo attribute. That's fine...until, some day down the road, I decide that getting and/or setting the foo attribute needs to do something a bit more complex. Or maybe I remove the $.foo attribute all together and replace it with a collection of other attributes or something. I can do that by writing my own foo() method, but there's the problem of all the existing code out there that says $obj.foo = whatever. In order to continue to support that, I have to provide an lvalue. As has been pointed out, I can use "will STORE" to add the "extra" behavior while continuing to use $.foo (or a proxy object, yadda) as my lvalue. But I find that slightly kludgy. If the default accessor had instead been defined like (the Perl 6 equivalent) of this: sub name { @_ > 1 ? $_[0]->{'foo'} = $_[1] : $_[0]->{'foo'} } then I wouldn't have any existing code doing $obj.foo = whatever to worry about. So extending my foo() accessor by writing my own method would be straight-forward. Another alternative is to have a simpler, more direct way to continue to support the $obj.foo = whatever semantics by writing a particular kind of foo() method. I don't like piling the "side effects" into a "will STORE" trait, since in version 4.0 of my class there could be a ton of code hanging off that hook. It just looks like the wrong place to put that. I'd rather have all the fancy things done when I call $obj.foo() defined in method foo { }. A final alternative is to never use the default accessor that I get when my class "has $.foo is rw" because that means having to support $obj.foo = whaever semantics forever and ever. But that means I have to write (the Perl 6 equivalent of) this: sub name { @_ > 1 ? $_[0]->{'foo'} = $_[1] : $_[0]->{'foo'} } for every single attribute. That's tiresome. Basically, I'm wondering exactly who is the target audience for the default accessor? It seems to tie the API to a very confining set of behaviors, and expose more of the internals of a class than I'd like. If $ob.foo will really never expand beyond a simple get/set interface to an attribute, it works fine. But that's rarely true in the long term, IME. It also, I think, creates an artificial distinction between those "simple" attributes that users can expect to set with $obj.foo = whatever, and the more complex attributes that must be set with $obj.foo(whatever). I'd like more symmetry in my APIs, but then I'm faced with the options describe above, none of which are as appealing as I'd like. I think others will also value API symmetry and will therefore either create their own "old-style" accessors everywhere, or (more likely) go to heroic measures to support $obj.foo = whatever everywhere, forever, probably by dangling 80% of their attribute accessor methdod code off of "will STORE" hooks by the time version 4.0 cof their class rolls around. That's not pleasant, IMO. -John