> -----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