class Metamodel::ClassHOW
class Metamodel::ClassHOW
does Metamodel::Naming
does Metamodel::Documenting
does Metamodel::Versioning
does Metamodel::Stashing
does Metamodel::AttributeContainer
does Metamodel::MethodContainer
does Metamodel::PrivateMethodContainer
does Metamodel::MultiMethodContainer
does Metamodel::RoleContainer
does Metamodel::MultipleInheritance
does Metamodel::DefaultParent
does Metamodel::C3MRO
does Metamodel::MROBasedMethodDispatch
does Metamodel::MROBasedTypeChecking
does Metamodel::Trusting
does Metamodel::BUILDPLAN
does Metamodel::Mixins
does Metamodel::ArrayType
does Metamodel::BoolificationProtocol
does Metamodel::REPRComposeProtocol
does Metamodel::Finalization
{ }
Warning: this class is part of the Rakudo implementation, and is not a part of the language specification.
Metamodel::ClassHOW
is the metaclass behind the class
keyword.
say so Int.HOW ~~ Metamodel::ClassHOW; # OUTPUT: «True»
say Int.^methods(:all).pick.name; # OUTPUT: «random Int method name»
Methods
method add_fallback
method add_fallback($obj, $condition, $calculator)
Installs a method fallback, that is, add a way to call methods that weren't statically added.
Both $condition
and $calculator
must be callables that receive the
invocant and the method name once a method is called that can't be found in
the method cache.
If $condition
returns a true value,
$calculator
is called with the same arguments, and must return the code
object to be invoked as the method, and is added to the method cache.
If $condition
returns a false value, the
next fallback (if any) is tried, and if none matches, an exception
of type X::Method::NotFound is thrown.
User-facing code (that is, code not dabbling with metaclasses) should use
method FALLBACK
instead.
method can
method can($obj, $method-name)
Given a method name, it returns a List of methods that are available with this name.
class A { method x($a) {} };
class B is A { method x() {} };
say B.^can('x').elems; # OUTPUT: «2»
for B.^can('x') {
say .arity; # OUTPUT: «1, 2»
}
In this example, class B
has two possible methods available with name x
(though a normal method call would only invoke the one installed in B
directly). The one in B
has arity 1 (i.e. it expects one argument, the
invocant (self
)), and the one in A
expects 2 arguments (self
and
$a
).
method lookup
method lookup($obj, $method-name --> Method:D)
Returns the first matching Method with the provided name. If no
method was found, returns a VM-specific sentinel value (typically a low-level
NULL value) that can be tested for with a test for
definedness. It is potentially faster than .^can
but does
not provide a full list of all candidates.
say Str.^lookup('Int').raku; # OUTPUT: «method Int (Str:D $: *%_) { #`(Method|39910024) ... }»
for <upper-case uc> {
Str.^lookup: $^meth andthen .("foo").say
orelse "method `$meth` not found".say
}
# OUTPUT:
# method `upper-case` not found
# FOO
method compose
method compose($obj)
A call to compose
brings the metaobject and thus the class it represents
into a fully functional state, so if you construct or modify a class, you must
call the compose method before working with the class.
It updates the method cache, checks that all methods that are required by roles are implemented, does the actual role composition work, and sets up the class to work well with language interoperability.
method new_type
method (:$name, :$repr = 'P6opaque', :$ver, :$auth)
Creates a new type from the metamodel, which we can proceed to build
my $type = Metamodel::ClassHOW.new_type(name => "NewType",
ver => v0.0.1,
auth => 'github:raku' );
$type.HOW.add_method($type,"hey", method { say "Hey" });
$type.hey; # OUTPUT: «Hey»
$type.HOW.compose($type);
my $instance = $type.new;
$instance.hey; # OUTPUT: «Hey»
We add a single method by using
Higher Order Workings methods, and
then we can use
that method directly as class method; we can then compose
the type, following
which we can create already an instance, which will behave in the exact same
way.