|
| 1 | +=begin pod :kind<Type> :subkind<role> :category<metamodel> |
| 2 | + |
| 3 | +=TITLE role Metamodel::TypePretense |
| 4 | + |
| 5 | +=SUBTITLE Metarole for type pretenses |
| 6 | + |
| 7 | + role Metamodel::TypePretense { } |
| 8 | + |
| 9 | +I<Warning>: this role is part of the Rakudo implementation, and is not |
| 10 | +a part of the language specification. |
| 11 | + |
| 12 | +Any role will type-check as L<C<Mu>|/type/Mu>, L<C<Any>|/type/Any>, and L<C<Cool>|/type/Cool>, but don't |
| 13 | +actually have these classes as parents: |
| 14 | + |
| 15 | +=begin code |
| 16 | +class Class { } |
| 17 | +role Role { } |
| 18 | + |
| 19 | +say Role ~~ Mu; # OUTPUT: «True» |
| 20 | +say Role ~~ Any; # OUTPUT: «True» |
| 21 | +say Role ~~ Cool; # OUTPUT: «True» |
| 22 | + |
| 23 | +say Class.^parents(:all).map(*.^name); # OUTPUT: «(Any Mu)» |
| 24 | +say Role.^pun.^parents(:all).map(*.^name); # OUTPUT: «()» |
| 25 | +=end code |
| 26 | + |
| 27 | +C<Metamodel::TypePretense> is the metarole that's responsible for this |
| 28 | +behavior. Using the metamethods this provides, types can C<pretend to |
| 29 | +be> other types, i.e. types can type-check as other types. This can be |
| 30 | +useful when implementing types that should not store parent types |
| 31 | +through |
| 32 | +L<C<Metamodel::MultipleInheritance>|/type/Metamodel::MultipleInheritance>, |
| 33 | +but should still type-check like other types somehow. |
| 34 | + |
| 35 | +All this metarole does is provide an interface for storing type objects |
| 36 | +in a HOW and provide a default C<type_check> method that allows types to |
| 37 | +type-check as the types they're pretending to be if no other |
| 38 | +type-checking behavior for it exists; any other behavior related to type |
| 39 | +pretenses are left up to the metaclasses that do this metarole to |
| 40 | +implement themselves. |
| 41 | + |
| 42 | +Because type pretenses are a property of the metaclass for a HOW, not |
| 43 | +HOWs themselves, the C<pretend_to_be> and C<pretending_to_be> |
| 44 | +metamethods this metarole provides must be invoked directly through a |
| 45 | +metaclass or HOW, not with C<.^> syntax: |
| 46 | + |
| 47 | +=for code :preamble<role Role { }> |
| 48 | +say Role.HOW.pretending_to_be.map(*.^name); # OUTPUT: «(Cool Any Mu)» |
| 49 | + |
| 50 | +This metarole is commonly used in combination with |
| 51 | +L<C<Metamodel::MethodDelegation>|/type/Metamodel::MethodDelegation>. |
| 52 | + |
| 53 | +=head1 Methods |
| 54 | + |
| 55 | +=head2 method pretend_to_be |
| 56 | + |
| 57 | + method pretend_to_be(@types) |
| 58 | + |
| 59 | +Makes all types for a type of HOW pretend to be any of the type objects |
| 60 | +in C<@types>. |
| 61 | + |
| 62 | +=head2 method pretending_to_be |
| 63 | + |
| 64 | + method pretending_to_be() |
| 65 | + |
| 66 | +Returns the type objects this type of HOW is pretending to be. |
| 67 | + |
| 68 | +=head2 method type_check |
| 69 | + |
| 70 | + method type_check($obj, $checkee) |
| 71 | + |
| 72 | +If C<$checkee> is the same object as C<$obj> or is of any of the types |
| 73 | +C<$obj> is pretending to be, returns C<1>, otherwise returns C<0>. |
| 74 | + |
| 75 | +=end pod |
0 commit comments