This file was automatically generated from http://svn.pugscode.org/pugs/misc/Perl-MetaModel/docs/perl6_meta_meta_class_hierarchy.pod on Thu Jul 12 12:23:25 2007 GMT, revision 16992.
This document attempts to explain the Meta-Meta-Class hierarchy and implementation.
.............> MetaClass <...............
: | : ---> isSubclassOf
: | : ...> isInstanceOf
: V : - -> does()
: Class::Behavior<----------+ :
: | | :
: | | :
: V | :
: +------> Role::Behavior | :
: | | | :
metaclass(Role) | ..... > metaclass(Class)
^ V :
: Object :
: | :
: | :
: V :
Role < - - - - - Class ...
role Role {}
class Class does Role {}
class Object is Class {}
class Role::Behavior is Object {}
class Class::Behavior is Role::Behavior {}
class MetaClass is Class::Behavior {}
my $Role = MetaClass.new('Role');
$Role.superclass(Role::Behavior);
my $Class = MetaClass.new('Class');
$Class.superclass(Class::Behavior);
$Class.roles($Role);
Or a sligthly different view of the same:
+--{ Implementation Layer }--------------------+
| | ---> isSubclassOf
| +----------->Role::Behavior | ...> isInstanceOf
| | ^ | - -> does()
| | | |
| | Class::Behavior<-----------+ |
| | ^ | |
+---|------------------|-------------------|---+
| | | | |
| | | | |
| Role .........> MetaClass <.......... Class |
| ^ | |
| + - - - - - - - - - - - - - - - - - - -+ |
| |
+---------------{ Meta Space }-----------------+
A Role is flattened into either a Class or another Role. This act of flattening negates any real "hierarchy" like that of a Class hierarchy.
This is an important distinction to remember.
Duck typing is usually described like this:
If it quacks like a duck, it must be a duck.
Which basically means that a Type is defined by the methods it responds to, instead of some label it has been given. However, this is a very simple defintion of duck-typing from the users point of view, and fails to explain it from the implementation point of view.
From the implementation point-of-view, duck-typing means that instead of an object's behavior being defined by a class, it is defined by a Type entity which exists in the somewhat muddy area between Class and Instances.
[ Class + [ Role, ... ]] --> ::Type <--- Instances
A class and it's attached roles are "compiled" into a Type, which is then used by instances in the system.
The behavior of classes and roles must be described somehow, and we should be able to re-use that implementation as well.
I propose a Class::Behavior and Role::Behavior implementation.
A Role::Behavior has a hash of methods and a hash of properties, as well as an array of Roles. Role::Behavior encapsulates all of the behavior needed to compose a Role.
A Class::Behavior is a subclass of Role::Behavior because a class also has a hash of methods and properties and an array of roles. It then adds to that with a parent class as well as a set of subclasses. Class::Behavior encapsulates all of the behavior needed to compose a Class.
The Meta Space contains all of our meta-objects of which I see 3 distinct types.
The Class too is an instance of the MetaClass, and it is a subclass of Class::Behavior.
The Class also does() the role Role.
NOTE: this Class.does(Role) relationship may not be needed, but I am leaving it in for now.
metametaclass MetaClass is Class::Behavior {
has $.name;
has @:roles;
has $:superclass;
has @:subclasses;
has %.properties;
has %.methods;
method addProperties {}
method addMethods {}
method invokeMethod {}
method super { ... } # a class must be able to inherit from another class
method subclasses { ... } # a class must be able to be inherited from
method doesRole {} # doing a Role just folds properties and methods into the metaclass
}
my $Role = MetaClass.new('Role'); # metaclass(Role) is an instance of metametaclass(MetaClass)
$Role.superclass(Role::Behavior);
$Role.addProperties(
$.name,
@:roles,
%:properties,
%:methods
);
$Role.addMethods(
roles
);
# Hmmm,... MetaClass and Role look suspiciously similar
my $Class = MetaClass.new('Class'); # metaclass(Class) is an instance of metametaclass(MetaClass)
$Class.superclass(Class::Behavior);
$Class.doesRole($Role);
$Class.addProperties(
$:superclass,
@:subclasses
);
$Class.addMethods(
super,
subclasses,
invokeMethod
);
When "compiled" the metaclass(Role) will look something like this:
metaclass Role is Role::Behavior {
has $.name;
has @.roles;
has %.properties;
has %.methods;
method roles { ... } # a role must be able to attach other roles to it
# property access is made possible through methods
}
NOTE: In order for the metaclass(Role) to be able to compose more roles, it must
have all the methods of a Role::Behavior. Since we don't want these methods to
actually be inherited down to the next level (the "user" space), we make the
metaclass inherit from Role::Behavior in the implementation itself, and not as a
superclass(). The same is done for metaclass(Class) and Class::Behavior.
my $bar_role = Role.new('Bar'); # role(Bar) is an instance of metaclass(Role)
$bar_role.addProperties(
$.baz
);
$bar_role.addMethods(
baz
);
Can then be "compiled" into this role(Bar):
role Bar {
has $.baz;
method baz { ... }
}
When "compiled" the metaclass(Class) will look like this:
metaclass Class is Class::Behavior does metaclass(Role) {
# the following properties are from metaclass(Role)
# $.name, @.roles, %.properties, %.methods;
# the following methods too
# roles(), invokeMethod()
has @.superclasses;
has @.subclasses;
method super { ... } # a class must be able to inherit from another class
method subclasses { ... } # a class must be able to be inherited from
method invokeMethod { ... }
}
my $foo_class = Class.new('Foo'); # class(Foo) is an instance of metaclass(Class)
$foo_class.doesRole('Bar');
$foo_class.addProperties(
$.foo
);
$foo_class.addMethods(
foo
);
This can then be compiled into this class(Foo):
class Foo {
has $.foo;
has $.baz;
method foo { ... }
method baz { ... }
}
Stevan Little <stevan@iinteractive.com>