=begin pod

=TITLE class Metamodel::ClassHOW

=SUBTITLE Metaobject representing a Perl 6 class.

    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::InvocationProtocol
        does Metamodel::Finalization
            { }

C<Metamodel::ClassHOW> is the meta class behind the C<class> keyword.

    say so Int.HOW ~~ Metamodel::ClassHOW;      # True
    say say Int.^methods(:all).pick.name;       # sin

=head1 Methods

=head2 method add_fallback

    method add_fallback(Metamodel::ClassHOW:D: $condition, $calculator)

Installs a method fallback, that is, add a way to call methods that weren't
statically added.

Both C<$condition> and C<$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 C<$condition> returns a true value,
C<$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 C<$condition> returns a false value, the
next fallback (if any) is tried, and if none matches, an exception
L<of type X::Method::NotFound|/type/X::Method::NotFound> is thrown.

User-facing code (that is, ,code not dabbling with meta classes) should use
method C<FALLBACK> instead.

=head2 method can

    method can(Metamodel::ClassHOW:D: $obj, $method-name)

Given a method names, it returns a L<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;              # 2
    for B.^can('x') {
        say .arity;                     # 1, 2
    }

In this example, class C<B> has two possible methods available with name C<x>
(though a normal method call would only invoke the one installed in C<B>
directly). The one in C<B> has arity 1 (i.e. it expects one argument, the
invocant (C<self>)), and the one in C<A> expects 2 arguments (C<self> and
C<$a>).

=end pod
