On Oct 12, 2005, at 09:41, Stevan Little wrote:
If you use the BUILD submethod, then you never need to worry about
a that, everything is initialized for you by BUILDALL. Now, if you
want to have a constructor which accepts positional arguments
rather than named pairs (as the default does), then you have a
valid need to override &new. Whether you should force this upon all
your subclasses is a matter of opinion I think.
For varying definitions of initialized. I never much cared for the
bare "poke stuff straight into my instance variables" constructor
along the lines of:
sub new {
my($class, %ARGS);
return bless \%ARGS, $class;
}
That more or less robs the constructor of the "behavior" part of
"class = state + behavior." I need an opportunity to establish my
invariants.
Of course, when there is no such behavior, it saves a lot of
repetitive typing in the class. C# 3 is finally growing a syntax that
resolves this by having the language do the repetitive typing at the
call site...
X x = new X{ Y = 1, Z = 2 };
means
X x = new X();
x.Y = 1;
x.Z = 2;
And X doesn't need anything but the default constructor.
Now, this is not to say that it cannot be made to do so. A slight
change to the above diagram allows for inheritence of "class
methods" very easily.
Class
^
:
eFoo<.......eBar
^ ^
| |
Foo<.......Bar
Now, method dispatch for Bar will go first to it's class (eBar),
then to any superclasses (eFoo), and any of their superclasses
(Class), and so on, and so forth. A better diagram of this can be
found here (http://svn.openfoundry.org/pugs/perl5/Perl6-MetaModel/
docs/Method_Dispatch_w_EigenClasses.jpg).
This is more or less how class methods have to work. I would go a bit
further, though. Too implement this:
Foo : Object
Foo : Bar
The runtime should use an inheritance tree as such:
Object
Class : Object
Foo : Object
Bar : Foo
_Object : Class
_Class : _Object
_Foo : _Class
_Bar : _Foo
Note that every declared class, including Object and Class
themselves, have an anonymous Class subclass that precisely parallels
the declared inheritance chain. (Chicken and egg problem? Probably.
Object and Class are Special.)
With this implementation, there are three places to put state: In
MyObject (instance variable), in _MyObject (class instance variable),
or outside of any instance (class variable). The class instance
variable is the least useful of the three.
Note: I don't see much value in invoking class methods through
instances, since a Foo IS_NOT_A Class. If one wants to save the user
typing ".class" when invoking class methods through an instance, I
would tend toward resolving it as such:
class Foo {
class_method int Bar(int i) { return i * i; }
}
-- BECOMES --
# Common interface for Foo's class methods.
interface _IFoo {
method int Bar(int i);
}
# The anonymous Class.
class _Foo extends Class implements _IFoo {
int Bar(int i) { return i * i; }
}
# The visible class.
class Foo implements _IFoo {
# Forwards the call to the Class.
void Bar(...) { return this.Class.Bar(...); }
}
I'll leave the probably obvious role-based interpretation of this to
those versed in such. :)
And I'm going to shut my yap, now, having butted into the middle of a
discussion of a hopelessly complex runtime that I haven't been
following for a 18 months. :)
—
Gordon Henriksen
[EMAIL PROTECTED]