Larry Wall wrote: > > Users of the class includes people subclassing the class, so to them > > they need to be able to use $.month_0 and $.month, even though there > > is no "has $.month_0" declared in the Class implementation, only > > "has $.month".
We thought about defining the attribute variables that way, but decided that it would be clearer if they only ever refer to real attributes declared in the current class.
Clearer in what way? This implies that you cannot; - refactor classes into class heirarchies without performing code review of all methods in the class and included roles. - "wrap" internal attribute access of a superclass in a subclass This in turn implies that the $.foo syntax is, in general, bad practice! Allow me to demonstrate with an example, taken from S12 with additions: role Pet { has $.collar = { Collar.new(Tag.new) }; method id () { return $.collar.tag } method lose_collar () { undef $.collar } has $.owner; } class Dog does Pet { has $.location; has $.home; does Run; method play { if $owner.location ~~ $.location { $?SELF.lose_collar(); } else { $?SELF.run(); } } } Now, as a user of the "Dog" class, I want to specialise it so that the collar cannot be removed unless the dog is at home; class Rotweiler is Dog { method collar { Proxy.new( STORE => sub($self, $val) { if ($val or $.location ~~ $.home) { $self.SUPER::collar = $val; } else { die "rotweilers must be kept on a leash" } }, FETCH => { $self.SUPER::collar }, ); } } OK, so that's all well and good - you've changed the public property "collar" so that your extra logic is there. But what happens? You lend your dog to someone else, they call $dog.play, which calls lose_collar(), which sets $.collar directly. Whoops, your Rotweiler is on the loose and slobbering over some unsuspecting 4 year old. This means that people designing classes and roles have to conciously make the decision to use $?SELF.foo or ./foo() instead of the more tempting looking and consistent $.foo Perhaps you could elucidate your point by giving some examples of when you *wouldn't* want $.foo to mean ./foo(), and when using a private attribute would not be the "correct" solution.
: These simple definitions should make all sorts of OO tricks possible, : and reduces the definition of Classes to one that is purely : functional (ie, state is just a set of functions too). One can certainly rewrite $.foo and $:foo in terms of lower level functional primitives, but we must be careful not to confuse those with higher-level virtual method calls. Otherwise we are mixing OO interface with OO implementation, and we've already discovered in Perl 5 that that's a Bad Idea.
Funnily enough, I found in Perl 5 that it's a good idea. Perhaps I should demonstrate; package MyObject; use base qw( Class::Tangram ); # define a string accessor for attribute "foo" our $fields = { string => ["foo"] }; sub get_foo { my $self = shift; return $self->SUPER::get_foo . "bar"; } sub set_foo { my $self = shift; my $new_foo = shift; return $self->SUPER::set_foo($new_foo . "baz"); } package main; my $object = MyObject->new(foo => "foo"); print $object->foo, "\n"; # prints "foobazbar" As you can see, instead of ever looking into the object's internal state, the "superclass" accessor is always used to find the object's internal state. This happens by munging @ISA at 'schema import' time, and building the accessors in an extra inserted class. Never do you have to use $object->{foo}; in a sense, so long as you don't circumvent the designed interface, the objects are already "opaque".
Interfaces between organisms are cleaner when their innards stay in and their outtards stay out.
Cleaner, perhaps - but how will they ever reproduce? Seriously, this isn't about innards (private attributes/properties) and outtards (public attributes/properties). This is about if you make a new version and replace one of the outtards, that the replaced outtards are not used anyway. Perhaps it would be better to stick to mechanical things. As you have already stated you do not want to include general Quantum Mechanical theory of extended entanglement into Perl 6 [1], it is unlikely that we will be designing organisms with it. Organisms do not fit the mould; they do not reduce easily into clean components, each piece of the whole is connected to the other via a quantum entanglement field. It is therefore not object oriented as the internal state of every part of the system affects the whole. So, I will use the analogy of an Automobile. If you replace the Engine of the automobile, you wouldn't want to have to replace the accelerator because it worked on the old $.engine. You just make sure all the engine responds correctly to the messages passed to it via the formal defined interface and go for a ride. Sam. 1. http://xrl.us/gsmd