Skip to content

Commit 9a2cfac

Browse files
committed
Manually apply PR#3352
"Document Metamodel::TypePretense and Metamodel::MethodDelegation" RIP Kaiepi++
1 parent e9d148f commit 9a2cfac

File tree

5 files changed

+170
-14
lines changed

5 files changed

+170
-14
lines changed

doc/Type/Metamodel/CurriedRoleHOW.rakudoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ a single parameter an instantiated role will also be of the same type:
6262
role Zape[::T] {};
6363
say Zape[Int].HOW; #: «Perl6::Metamodel::CurriedRoleHOW.new␤»
6464

65+
Curried roles L<pretend to be|/type/Metamodel::TypePretense> of types
66+
L<C<Mu>|/type/Mu>, L<C<Any>|/type/Any>, and L<C<Cool>|/type/Cool>, and
67+
L<delegate|/type/Metamodel::MethodDelegation> methods to L<C<Any>|/type/Any>.
68+
6569
I<Note>: As with most of the C<Metamodel> classes, this one is mainly for illustration
6670
purposes and is not intended for the end user to instantiate.
6771

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
=begin pod :kind<Type> :subkind<role> :category<metamodel>
2+
3+
=TITLE role Metamodel::MethodDelegation
4+
5+
=SUBTITLE Metarole for delegating method dispatch
6+
7+
role Metamodel::MethodDelegation { }
8+
9+
I<Warning>: this role is part of the Rakudo implementation, and is not
10+
a part of the language specification.
11+
12+
Methods of L<C<Any>|/type/Any> and L<C<Mu>|/type/Mu> can be invoked on roles, despite them not
13+
actually having these types as parents:
14+
15+
=begin code
16+
role Role { }
17+
18+
say Role.raku; # OUTPUT: «Role␤»
19+
say Role.^pun.^parents(:all).map(*.^name); # OUTPUT: «()␤»
20+
=end code
21+
22+
C<Metamodel::MethodDelegation> is the metarole responsible for this
23+
behavior. Using the metamethods this provides, metaobjects can delegate
24+
method dispatch to another type object. This can be useful when
25+
implementing types that shouldn't store methods of their own through
26+
L<C<Metamodel::MethodContainer>|/type/Metamodel::MethodContainer>, but
27+
should still support method dispatch somehow.
28+
29+
All this metarole does is provide an interface for storing a type object
30+
to delegate methods to and provide a default C<find_method> method for
31+
delegating method lookups to that type object if no other method lookup
32+
behavior for it exists; any other behavior related to methods is left up
33+
to the metaclasses that do this metarole to implement themselves.
34+
35+
Because method delegation is a property of the metaclass for a HOW, not
36+
HOWs themselves, the C<delegate_methods_to> and
37+
C<delegating_methods_to> metamethods this metarole provides must be
38+
invoked directly through a metaclass or HOW, not with C<.^> syntax:
39+
40+
=for code :preamble<role Role { }>
41+
say Role.HOW.delegating_methods_to.^name; # OUTPUT: «Any␤»
42+
43+
This metarole is commonly used in combination with
44+
L<C<Metamodel::TypePretense>|/type/Metamodel::TypePretense>.
45+
46+
=head1 Methods
47+
48+
=head2 method delegate_methods_to
49+
50+
method delegate_methods_to($type)
51+
52+
Delegates methods to C<$type>. This should be a type object, but may be
53+
any object with a C<find_method> metamethod technically.
54+
55+
=head2 method delegating_methods_to
56+
57+
method delegating_methods_to()
58+
59+
Returns the type object a metaobject is delegating methods to.
60+
61+
=head2 method find_method
62+
63+
method find_method($obj, $name)
64+
65+
Looks up a method on the type object this metaobject is delegating
66+
method dispatch to.
67+
68+
=end pod

doc/Type/Metamodel/ParametricRoleGroupHOW.rakudoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
=SUBTITLE Represents a group of roles with different parameterizations
66

7+
:for code :solo
78
class Metamodel::ParametricRoleGroupHOW
89
does Metamodel::Naming
910
does Metamodel::Documenting
@@ -28,6 +29,10 @@ my \zape := Metamodel::ParametricRoleGroupHOW.new_type( name => "zape");
2829
my \zipi := Metamodel::ParametricRoleHOW.new_type( name => "zipi", group => zape);
2930
say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤»
3031

32+
Role groups L<pretend to be|/type/Metamodel::TypePretense> of types
33+
L<C<Mu>|/type/Mu>, L<C<Any>|/type/Any>, and L<C<Cool>|/type/Cool>, and
34+
L<delegate|/type/Metamodel::MethodDelegation> methods to L<C<Any>|/type/Any>.
35+
3136
I<Note>: As with most of the C<Metamodel> classes, this one is mainly for illustration
3237
purposes and is not intended for the end user to instantiate.
3338

doc/Type/Metamodel/ParametricRoleHOW.rakudoc

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
=SUBTITLE Represents a non-instantiated, parameterized, role.
66

77
=for code :skip-test<TWEAK>
8-
class Metamodel::ParametricRoleHOW
9-
does Metamodel::Naming
10-
does Metamodel::Documenting
11-
does Metamodel::Versioning
12-
does Metamodel::MethodContainer
13-
does Metamodel::PrivateMethodContainer
14-
does Metamodel::MultiMethodContainer
15-
does Metamodel::AttributeContainer
16-
does Metamodel::RoleContainer
17-
does Metamodel::MultipleInheritance
18-
does Metamodel::Stashing
19-
does Metamodel::TypePretense
20-
does Metamodel::RolePunning
21-
does Metamodel::ArrayType {}
8+
class Metamodel::ParametricRoleHOW
9+
does Metamodel::Naming
10+
does Metamodel::Documenting
11+
does Metamodel::Versioning
12+
does Metamodel::MethodContainer
13+
does Metamodel::PrivateMethodContainer
14+
does Metamodel::MultiMethodContainer
15+
does Metamodel::AttributeContainer
16+
does Metamodel::RoleContainer
17+
does Metamodel::MultipleInheritance
18+
does Metamodel::Stashing
19+
does Metamodel::TypePretense
20+
does Metamodel::RolePunning
21+
does Metamodel::ArrayType {}
2222

2323
I<Warning>: this class is part of the Rakudo implementation, and is not
2424
a part of the language specification.
@@ -39,6 +39,10 @@ say zipi.HOW; # OUTPUT: «Perl6::Metamodel::ParametricRoleHOW.new␤»
3939
The extra C<group> argument will need to be used to integrate it in a parametric
4040
role group, which will need to be defined in advance.
4141

42+
Roles L<pretend to be|/type/Metamodel::TypePretense> of types L<C<Mu>|/type/Mu>,
43+
L<C<Any>|/type/Any>, and L<C<Cool>|/type/Cool>, and L<delegate|/type/Metamodel::MethodDelegation>
44+
methods to L<C<Any>|/type/Any>.
45+
4246
I<Note>: As with most of the C<Metamodel> classes, this one is mainly for illustration
4347
purposes and is not intended for the end user to instantiate.
4448

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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

Comments
 (0)