diff --git a/doc/Type/Metamodel/CurriedRoleHOW.pod6 b/doc/Type/Metamodel/CurriedRoleHOW.pod6 index 6419535d7..7ecbb505c 100644 --- a/doc/Type/Metamodel/CurriedRoleHOW.pod6 +++ b/doc/Type/Metamodel/CurriedRoleHOW.pod6 @@ -61,6 +61,10 @@ a single parameter an instantiated role will also be of the same type: role Zape[::T] {}; say Zape[Int].HOW; #: «Perl6::Metamodel::CurriedRoleHOW.new␤» +Curried roles L of types +C, C, and C, and +L methods to C. + I: As most of the C classes, this class is here mainly for illustration purposes and it's not intended for the final user to instantiate. diff --git a/doc/Type/Metamodel/MethodDelegation.pod6 b/doc/Type/Metamodel/MethodDelegation.pod6 new file mode 100644 index 000000000..30f6023a9 --- /dev/null +++ b/doc/Type/Metamodel/MethodDelegation.pod6 @@ -0,0 +1,68 @@ +=begin pod :kind :subkind :category + +=TITLE role Metamodel::MethodDelegation + +=SUBTITLE Metarole for delegating method dispatch + + role Metamodel::MethodDelegation { } + +I: this role is part of the Rakudo implementation, and is not +a part of the language specification. + +Methods of C and C can be invoked on roles, despite them not +actually having these types as parents: + +=begin code +role Role { } + +say Role.raku; # OUTPUT: «Role␤» +say Role.^pun.^parents(:all).map(*.^name); # OUTPUT: «()␤» +=end code + +C is the metarole responsible for this +behavior. Using the metamethods this provides, metaobjects can delegate +method dispatch to another type object. This can be useful when +implementing types that shouldn't store methods of their own through +L|/type/Metamodel::MethodContainer>, but +should still support method dispatch somehow. + +All this metarole does is provide an interface for storing a type object +to delegate methods to and provide a default C method for +delegating method lookups to that type object if no other method lookup +behavior for it exists; any other behavior related to methods is left up +to the metaclasses that do this metarole to implement themselves. + +Because method delegation is a property of the metaclass for a HOW, not +HOWs themselves, the C and +C metamethods this metarole provides must be +invoked directly through a metaclass or HOW, not with C<.^> syntax: + +=for code :preamble +say Role.HOW.delegating_methods_to.^name; # OUTPUT: «Any␤» + +This metarole is commonly used in combination with +L|/type/Metamodel::TypePretense>. + +=head1 Methods + +=head2 method delegate_methods_to + + method delegate_methods_to($type) + +Delegates methods to C<$type>. This should be a type object, but may be +any object with a C metamethod technically. + +=head2 method delegating_methods_to + + method delegating_methods_to() + +Returns the type object a metaobject is delegating methods to. + +=head2 method find_method + + method find_method($obj, $name) + +Looks up a method on the type object this metaobject is delegating +method dispatch to. + +=end pod diff --git a/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 b/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 index 9ba35ec9d..03cc83a3a 100644 --- a/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 +++ b/doc/Type/Metamodel/ParametricRoleGroupHOW.pod6 @@ -28,6 +28,10 @@ my \zape := Metamodel::ParametricRoleGroupHOW.new_type( name => "zape"); my \zipi := Metamodel::ParametricRoleHOW.new_type( name => "zipi", group => zape); say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» +Role groups L of types +C, C, and C, and +L methods to C. + I: As most of the C classes, this class is here mainly for illustration purposes and it's not intended for the final user to instantiate. diff --git a/doc/Type/Metamodel/ParametricRoleHOW.pod6 b/doc/Type/Metamodel/ParametricRoleHOW.pod6 index b4ac7f736..c02e4ef6f 100644 --- a/doc/Type/Metamodel/ParametricRoleHOW.pod6 +++ b/doc/Type/Metamodel/ParametricRoleHOW.pod6 @@ -38,6 +38,10 @@ say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤» The extra C argument will need to be used to integrate it in a parametric role group, which will need to be defined in advance. +Roles L of types C, +C, and C, and L +methods to C. + I: As most of the C classes, this one is here mainly for illustration purposes and it's not intended for the final user to instantiate, unless their intention is really to create a parametric role group. diff --git a/doc/Type/Metamodel/TypePretense.pod6 b/doc/Type/Metamodel/TypePretense.pod6 new file mode 100644 index 000000000..4695927ac --- /dev/null +++ b/doc/Type/Metamodel/TypePretense.pod6 @@ -0,0 +1,75 @@ +=begin pod :kind :subkind :category + +=TITLE role Metamodel::TypePretense + +=SUBTITLE Metarole for type pretenses + + role Metamodel::TypePretense { } + +I: this role is part of the Rakudo implementation, and is not +a part of the language specification. + +Any role will type-check as C, C, and C, but don't +actually have these classes as parents: + +=begin code +class Class { } +role Role { } + +say Role ~~ Mu; # OUTPUT: «True␤» +say Role ~~ Any; # OUTPUT: «True␤» +say Role ~~ Cool; # OUTPUT: «True␤» + +say Class.^parents(:all).map(*.^name); # OUTPUT: «(Any Mu)␤» +say Role.^pun.^parents(:all).map(*.^name); # OUTPUT: «()␤» +=end code + +C is the metarole that's responsible for this +behavior. Using the metamethods this provides, types can C other types, i.e. types can type-check as other types. This can be +useful when implementing types that should not store parent types +through +L|/type/Metamodel::MultipleInheritance>, +but should still type-check like other types somehow. + +All this metarole does is provide an interface for storing type objects +in a HOW and provide a default C method that allows types to +type-check as the types they're pretending to be if no other +type-checking behavior for it exists; any other behavior related to type +pretenses are left up to the metaclasses that do this metarole to +implement themselves. + +Because type pretenses are a property of the metaclass for a HOW, not +HOWs themselves, the C and C +metamethods this metarole provides must be invoked directly through a +metaclass or HOW, not with C<.^> syntax: + +=for code :preamble +say Role.HOW.pretending_to_be.map(*.^name); # OUTPUT: «(Cool Any Mu)» + +This metarole is commonly used in combination with +L|/type/Metamodel::MethodDelegation>. + +=head1 Methods + +=head2 method pretend_to_be + + method pretend_to_be(@types) + +Makes all types for a type of HOW pretend to be any of the type objects +in C<@types>. + +=head2 method pretending_to_be + + method pretending_to_be() + +Returns the type objects this type of HOW is pretending to be. + +=head2 method type_check + + method type_check($obj, $checkee) + +If C<$checkee> is the same object as C<$obj> or is of any of the types +C<$obj> is pretending to be, returns C<1>, otherwise returns C<0>. + +=end pod