Skip to content

Commit e15acbc

Browse files
committed
Re-purpose the method ^foo(...) { ... } syntax.
The existing design of it was out of line with the way Perl 6 evolved since then, and also not especially useful. This takes the syntax and enables its use for per-type meta-behavior specialization. This, as a special case, allows attaching extra metadata to the meta-object, which captures some aspect of what the syntax was originally specified to do. However, it maintains the distinction between objects and their meta-objects more strongly, which also fits better with the overall Perl 6 design.
1 parent d0ebd21 commit e15acbc

File tree

1 file changed

+46
-14
lines changed

1 file changed

+46
-14
lines changed

S12-objects.pod

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -624,22 +624,13 @@ you a choice. If you declare an ordinary method, it can function as a
624624
"class" method when you pass it a type object such as "C<Dog>" regardless
625625
of how defined the prototype object is, as long as the method body doesn't
626626
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:
627628

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+
}
634631

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.
643634

644635
=head1 Submethods
645636

@@ -2639,6 +2630,47 @@ many long names due to signatured roles.
26392630
role Foo[::T] {
26402631
}
26412632

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+
26422674
=head1 Autovivifying objects
26432675

26442676
The C<WHENCE> property of an object is its autovivifying closure.

0 commit comments

Comments
 (0)