The p6opaque Responder Interface is the default responder for all Perl 6 objects.
Composition
This is a hard topic in Perl 6, as compositions are mostly unpredictable (unless the class is closed). This way the composition is made with a "composition pile", where every composition operation is put in order, allowing correct method resolution. But the declarations in a class always override any composition declaration. That way, a prototype have:
- The composition pile (in order of composition)
- At compile time the order is:
- inheritance (reverse of the specified order)
- roles (in no particular order)
- At runtime the order is
- when composing with "is", it unshifts the pile
- when composing with "does", it pushes the pile
- The submethods
- The methods
- The attribute list (used during BUILD)
- Class storage
- each slot represents the class attributes' values
So the method lookup always:
- Looks for a member of the class
- goes bottom-up in the "composition pile" looking for the member
Private member lookup always:
- Look in the storage space for this class in the object
- Look in the class storage
An object, on the other hand, have
- Storage space for each participant of the composition (including the class itself), where each participant only sees its own space.
- each space contain slots for the attributes defined by that participant.
And an object that can autovivifies have:
- WHENCE closure to autovivify this object.
p6opaque Structure
Putting this all together, we get to the following structure that every object, defined or not (in which case it is a prototype), have:
- metadata
- composition pile
- class storage
- class definitions
- class attributes
- my Int $.foo
- my Bool $!bar
- instance attributes
- has Int $.baz
- has Bool $!buz
- methods
- method foo() is rw as Int { ... }
- submethods
- WHENCE
- instance storage
If an object have empty storage, it's a protoobject, if it have a WHENCE it can be autovivified. A normal object will have only a single "is" in the compostition pile and all other metadata empty, on the other hand, it might also have other information, which makes it a self-contained object that is also its own class.
- if an object have a single "is" in the composition pile and the rest of the metadata empty, then WHAT returns what this object "is", else it returns itself
- every object returns a different return to HOW. HOW modifies the object, not its prototype. $foo.^add_method(...) is not the same as $foo.WHAT.^add_method(...)