@@ -624,22 +624,13 @@ you a choice. If you declare an ordinary method, it can function as a
624
624
"class" method when you pass it a type object such as "C<Dog>" regardless
625
625
of how defined the prototype object is, as long as the method body doesn't
626
626
try to access any information that is undefined in the current instance.
627
+ Alternatively, a method can use the C<:U> type modifier on the invocant:
627
628
628
- Alternately, you can associate a method with the current metaclass instance,
629
- which as a singleton object knows your package, and can function as a
630
- more traditional "class" method:
631
-
632
- our $count;
633
- method ^count { return $count }
629
+ method oh_so_static(::?CLASS:U:) {
630
+ }
634
631
635
- Such a I<metaclass method> is always delegated to the C<HOW> object
636
- just as methods like C<.does> are, so it's possible to call this as
637
- C<Dog.count> or C<$dog.count>. However, best practice is probably to
638
- call such a class method as C<Dog.^count> or C<$dog.^count> to make it
639
- clear that it's in its own namespace separate from ordinary methods, and
640
- so that your class method cannot be accidentally overridden by an
641
- ordinary method in a subclass--presuming you don't want to allow for
642
- that possibility.
632
+ This will cause the method to actively refuse invocations on instances, and
633
+ only permit invocation through the type object.
643
634
644
635
=head1 Submethods
645
636
@@ -2639,6 +2630,47 @@ many long names due to signatured roles.
2639
2630
role Foo[::T] {
2640
2631
}
2641
2632
2633
+ Sometimes, it may be interesting to customize meta-object behaviour on a
2634
+ per-type basis. While this could be done by writing a custom meta-class and
2635
+ arranging for it to be used, Perl 6 permits overriding specific meta-methods
2636
+ on a per-type basis. For example, if the C<trusts> adverb was not flexible
2637
+ enough and the class instead wanted to implement a more custom policy on
2638
+ what other types it trusts, it could do something like:
2639
+
2640
+ method ^is_trusted($obj, $do_we_trust_it) {
2641
+ return $do_we_trust_it ~~ TheRoleOfTheTrustworthy;
2642
+ }
2643
+
2644
+ It's not necessary to override existing meta-methods either; this can be used
2645
+ to attach whatever properties are desired to the meta-object for the type:
2646
+
2647
+ method ^license($obj) { 'Artistic License' }
2648
+
2649
+ Note that meta-methods generally need to take an argument that corresponds to
2650
+ the object they are invoked on. This is because:
2651
+
2652
+ $obj.^license
2653
+
2654
+ Desugars to:
2655
+
2656
+ $obj.HOW.license($obj)
2657
+
2658
+ Meaning that implementing meta-methods providing prototype-like semantics are
2659
+ possible.
2660
+
2661
+ Methods declared with the C<^> modifier are handed to the meta-object by the
2662
+ C<add_meta_method> method, rather than the usual C<add_method>. At compose
2663
+ time of the class (usually, the closing C<}>), if there are any such per-type
2664
+ meta-methods, a role will be generated containing the meta-methods, and this
2665
+ will be mixed in to the meta-object. This means that this mechanism is only
2666
+ useful for overriding meta-methods called after class composition. Therefore,
2667
+ short of trying to restrict C<augment> operations in the future, it does not
2668
+ make sense to write a C<method ^add_method(...) { ... }>. Such declarational
2669
+ behaviour changes should be handled through the C<EXPORTHOW> approach. Any
2670
+ meta-methods in a role will not have immediate effect, but will rather be
2671
+ passed along to any class the role is composed into, and so take effect at
2672
+ composition time of each class composing the role.
2673
+
2642
2674
=head1 Autovivifying objects
2643
2675
2644
2676
The C<WHENCE> property of an object is its autovivifying closure.
0 commit comments