> -----Original Message----- > From: John Siracusa [mailto:[EMAIL PROTECTED] > Sent: Monday, 19 April, 2004 02:21 PM > To: Perl 6 Language > Subject: A12: default accessors and encapsulation > > > Let's say I have a class with some attributes: > > class Dog; > > has $.name is rw; > has $.age is rw; > has $.gender is rw; > > I initially decide to accept the default accessors. > > $dog.name = 'Ralph'; > print $dog.age; > > This works well for a while, but then I decide to update Dog so > that setting > the name also sets the gender. > > $dog.name = 'Susie'; # also sets $dog.gender to 'female' > > How do I write such a name() method? Do I just check the arg, set the > gender, and then return $.name as an "lvalue" or something?
class Afghan is Dog { does Hunter; does AKC; has $.name is rw will STORE { .set_name($^name); }; has $.taliban is OppressiveGovernment; method set_name($self: String $name) { DESTROY unless $.taliban.approves($name); given ($name) { when <Names::Female> { ... } ... } } } > > If so, what happens if, some time down the road, the $.name attribute goes > away entirely? I can't return it as an lvalue now, can I? method name(String ?$name) {...} > > Basically, I'm wondering how much of the object's internals I'm > exposing by accepting the default accessors. Since lvalue subs/methods are easy, and $obj.attr looks like $obj.method with no args, it should be pretty trivial to drop in a replacement if you decide you don't like the attribute-based solution. You are a little committed, since <$dog.name = "fred"> does assume that you've got a reference to something you can pass back, but that's about it. You can leave the "name" attribute around as a placeholder and let the STORE block update the "official" location, or you could return some sort of proxy-lvalue object that wasn't really a part of Dog: class WeaselDog is Dog { class PhonyAttr { $.store; $.fetch; method STORE { $.store($^value); return $_; } method FETCH { return $.fetch(); } } method set_name(String $name) {...} method get_name() {...} method name is rw { return new PhonyAttr( object => $_, store => { .set_name $^name; }, fetch => { .get_name; } ); } } =Austin