=begin pod :kind("Language") :subkind("Language") :category("fundamental")

=TITLE Object orientation

=SUBTITLE Object orientation in Raku

Raku provides strong support for L<Object Oriented Programming (OOP)|https://en.wikipedia.org/wiki/Object-oriented_programming>.
Although Raku allows programmers to program in multiple paradigms,
Object Oriented Programming is at the heart of the language.

Raku comes with a wealth of predefined types, which can be classified
in two categories: regular and L<I<native> types|/language/nativetypes>.
Everything that you can store in a variable is either a I<native value>
or an I<object>. That includes literals, types (type objects), code and
containers.

Native types are used for low-level types (like C<uint64>). Even if I<native>
types do not have the same capabilities as objects, if you call methods on them,
they are automatically I<boxed> into normal objects.

Everything that is not a I<native> value is an I<object>.
Objects do allow for both
L<inheritance|https://en.wikipedia.org/wiki/Object-oriented_programming#Inheritance_and_behavioral_subtyping> and
L<encapsulation|https://en.wikipedia.org/wiki/Object-oriented_programming#Encapsulation>.


=head1 Using objects

To call a method on an object, add a dot, followed by the method name:

=for code
say "abc".uc;
# OUTPUT: «ABC␤»

This calls the C<uc> method on C<"abc">, which is an object of type
C<Str>. To supply arguments to the method, add arguments inside parentheses
after the method.

=for code
my $formatted-text = "Fourscore and seven years ago...".indent(8);
say $formatted-text;
# OUTPUT: «        Fourscore and seven years ago...␤»

C<$formatted-text> now contains the above text, but indented 8 spaces.

Multiple arguments are separated by commas:

=for code :preamble<my $formatted-text;>
my @words = "Abe", "Lincoln";
@words.push("said", $formatted-text.comb(/\w+/));
say @words;
# OUTPUT: «[Abe Lincoln said (Fourscore and seven years ago)]␤»

Similarly, multiple arguments can be specified by placing a colon after
the method and separating the argument list with a comma:

=for code :preamble<my @words;>
say @words.join('--').subst: 'years', 'DAYS';
# OUTPUT: «Abe--Lincoln--said--Fourscore and seven DAYS ago␤»

Since you have to put a C<:> after the method if you want to pass
arguments without parentheses, a method call without a colon or
parentheses is unambiguously a method call without an argument list:

    say 4.log:   ; # OUTPUT: «1.38629436111989␤» ( natural logarithm of 4 )
    say 4.log: +2; # OUTPUT: «2␤» ( base-2 logarithm of 4 )
    say 4.log  +2; # OUTPUT: «3.38629436111989␤» ( natural logarithm of 4, plus 2 )

Many operations that don't look like method calls (for example,
smartmatching or interpolating an object into a string) might result in
method calls under the hood.

Methods can return mutable containers, in which case you can assign to the
return value of a method call. This is how read-writable attributes to
objects are used:

=for code
$*IN.nl-in = "\r\n";

Here, we call method C<nl-in> on the C<$*IN> object, without arguments,
and assign to the container it returned with the L<C<=>|/routine/=> operator.

All objects support methods from class L<Mu|/type/Mu>, which is the type
hierarchy root. All objects derive from C<Mu>.

Object equality needs a specific operator:
L<C<eqv>|/language/operators#infix_eqv>, the structural comparison
operator:

=for code
class Foo {
    has $.bar;
    has $.baz
};
my $bar = "42";
my $baz = 24;
my $zipi = Foo.new( :$baz, :$bar);
my $zape = Foo.new( :$bar, :$baz);
say $zipi eqv $zape; # OUTPUT: «True␤»

Object identity, on the other hand, uses C<===>. Using it above will return
C<False>, for instance.

X<|Type objects>
=head2 Type objects

Types themselves are objects and you can get the I<type object> by
writing its name:

=for code
my $int-type-obj = Int;

You can request the type object of anything by calling the C<WHAT>
method, which is actually a macro in method form:

=for code :ok-test<WHAT>
my $int-type-obj = 1.WHAT;

Type objects (other than L<Mu|/type/Mu>) can be compared for equality with the
L<C<===>|/routine/===> identity operator:

=for code :ok-test<WHAT>
sub f(Int $x) {
    if $x.WHAT === Int {
        say 'you passed an Int';
    }
    else {
        say 'you passed a subtype of Int';
    }
}

Although, in most cases, the L<C<.isa>|/routine/isa> method will suffice:

=for code
sub f($x) {
    if $x.isa(Int) {
        ...
    }
    ...
}

Subtype checking is done by L<smartmatching|/language/operators#infix_~~>:

=for code :preamble<my $type;>
if $type ~~ Real {
    say '$type contains Real or a subtype thereof';
}

=head1 X<Classes|declarator,class>

Classes are declared using the C<class> keyword, typically followed by a
name.

=for code
class Journey { }

This declaration results in a type object being created and installed in the
current package and current lexical scope under the name C<Journey>. You
can also declare classes lexically:

=for code
my class Journey { }

This restricts their visibility to the current lexical scope, which can be
useful if the class is an implementation detail nested inside a module or
another class.

=head2 Attributes
X<|Attribute> X<|Property> X<|Member> X<|Slot>

Attributes are variables that exist per instance of a class; when instantiated
to a value, the association between the variable and its value is called a
property. They are where the state of an object is stored. In Raku, all
attributes are I<private>, which means they can be accessed directly only by
the class instance itself. They are typically declared using the C<has>
declarator and the C<!> twigil.

=begin code
class Journey {
    has $!origin;
    has $!destination;
    has @!travelers;
    has $!notes;
}
=end code

While there is no such thing as a public (or even protected) attribute,
there is a way to have accessor methods generated automatically: replace the
C<!> twigil with the C<.> twigil (the C<.> should remind you of a method
call).

=begin code
class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes;
}
=end code

This defaults to providing a read-only accessor. In order to allow changes
to the attribute, add the L<is rw|/routine/is%20rw> trait:

=begin code
class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes is rw;
}
=end code

Now, after a C<Journey> object is created, its C<.origin>, C<.destination>,
and C<.notes> will all be accessible from outside the class, but only
C<.notes> can be modified.

If an object is instantiated without certain attributes, such as origin or
destination, we may not get the desired result. To prevent this, provide
default values or make sure that an attribute is set on object creation
by marking an attribute with an L<is required|/routine/is%20required> trait.

=begin code
class Journey {
    # error if origin is not provided
    has $.origin is required;
    # set the destination to Orlando as default (unless that is the origin!)
    has $.destination = self.origin eq 'Orlando' ?? 'Kampala' !! 'Orlando';
    has @!travelers;
    has $.notes is rw;
}
=end code

Since classes inherit a default constructor from C<Mu> and we have requested
that some accessor methods are generated for us, our class is already
somewhat functional.

=begin code :preamble<class Journey {};>
# Create a new instance of the class.
my $vacation = Journey.new(
    origin      => 'Sweden',
    destination => 'Switzerland',
    notes       => 'Pack hiking gear!'
);

# Use an accessor; this outputs Sweden.
say $vacation.origin;

# Use an rw accessor to change the value.
$vacation.notes = 'Pack hiking gear and sunglasses!';
=end code

Note that, although the default constructor can initialize read-only
attributes, it will only set attributes that have an accessor method.
That is, even if you pass C«travelers => ["Alex", "Betty"]» to the
default constructor, the attribute C<@!travelers> is not initialized.

=head2 Methods

Methods are declared with the C<method> keyword inside a class body.

=begin code
class Journey {
    has $.origin;
    has $.destination;
    has @!travelers;
    has $.notes is rw;

    method add-traveler($name) {
        if $name ne any(@!travelers) {
            push @!travelers, $name;
        }
        else {
            warn "$name is already going on the journey!";
        }
    }

    method describe() {
        "From $!origin to $!destination"
    }
}
=end code

A method can have a signature, just like a subroutine. Attributes can be
used in methods and can always be used with the C<!> twigil, even if they
are declared with the C<.> twigil. This is because the C<.> twigil
declares a C<!> twigil and generates an accessor method.

Looking at the code above, there is a subtle but important difference between
using C<$!origin> and C<$.origin> in the method C<describe>. C<$!origin>
is an inexpensive and obvious lookup of the attribute. C<$.origin> is a
method call and thus may be overridden in a subclass. Only use C<$.origin> if
you want to allow overriding.

Unlike subroutines, additional named arguments will not produce compile time or
runtime errors. That allows chaining of methods via
L<Re-dispatching|/language/functions#Re-dispatching>.

You may write your own accessors to override any or all of the autogenerated
ones.

=begin code
my $ⲧ = " " xx 4; # A tab-like thing
class Journey {
    has $.origin;
    has $.destination;
    has @.travelers;
    has Str $.notes is rw;

    multi method notes() { "$!notes\n" };
    multi method notes( Str $note ) { $!notes ~= "$note\n$ⲧ" };

    method Str { "⤷ $!origin\n$ⲧ" ~ self.notes() ~ "$!destination ⤶\n" };
}

my $trip = Journey.new( :origin<Here>, :destination<There>,
                        travelers => <þor Freya> );

$trip.notes("First steps");
notes $trip: "Almost there";
print $trip;

# OUTPUT:
#⤷ Here
#       First steps
#       Almost there
#
#There ⤶
=end code

The declared multi method C<notes> overrides the auto-generated
methods implicit in the declaration of C<$.notes>, using a different
signature for reading and writing.

Please note that in C<notes $trip: "Almost there"> we are using X<indirect
invocant syntax>, which puts first the method name, then the object, and then,
separated by a colon, the arguments: C<method invocant: arguments>. We can use
this syntax whenever it feels more natural than the classical
period-and-parentheses one. It works exactly in the same way.

Note how the call to the C<notes> method in the C<Str> method is made on
C<self>. Writing method calls this way will leave the return value of
the method as is with regards to containers. To containerize return
values, you can make method calls on a sigil instead of C<self>. This
calls various methods on the return value of the method depending on the
sigil used to containerize it:

=begin table
Sigil | Method
==============
 $    | item
 @    | list
 %    | hash
 &    | item
=end table

For example, the C<Str> method of C<Journey> can be rewritten not to use
the C<~> operator by embedding a sigiled method call in the string it
returns:

=begin code :skip-test<demonstrates another way of writing a method>
method Str { "⤷ $!origin\n$ⲧ$.notes()$!destination ⤶\n" }
=end code

Method names can be resolved at runtime with the C<.""> operator.

=begin code
class A { has $.b };
my $name = 'b';
A.new."$name"().say;
# OUTPUT: «(Any)␤»
=end code

The syntax used to update C<$.notes> changed in this section with respect
to the previous L<#Attributes> section. Instead of an assignment:

=for code :preamble<my $vacation>
$vacation.notes = 'Pack hiking gear and sunglasses!';

we now do a method call:

=for code :preamble<my $trip>
$trip.notes("First steps");

Overriding the default auto-generated accessor means it is no longer
available to provide a mutable container on return for an assignment.
A method call is the preferred approach to adding computation and
logic to the update of an attribute. Many modern languages can update
an attribute by overloading assignment with a “setter” method. While
Raku can overload the assignment operator for this purpose with a
L<C<Proxy>|https://github.com/Raku/roast/blob/master/S12-attributes/mutators.t>
object, overloading assignment to set attributes with complex logic is
currently discouraged as
L<weaker object oriented design|https://6guts.wordpress.com/2016/11/25/perl-6-is-biased-towards-mutators-being-really-simple-thats-a-good-thing/>.

=head2 Class and instance methods

A method's signature can have an I<explicit invocant> as its first parameter
followed by a colon, which allows for the method to refer to the object
it was called on.

=begin code
class Foo {
    method greet($me: $person) {
        say "Hi, I am $me.^name(), nice to meet you, $person";
    }
}
Foo.new.greet("Bob");    # OUTPUT: «Hi, I am Foo, nice to meet you, Bob␤»
=end code

Providing an invocant in the method signature also allows for defining
the method as either as a class method, or as an object method, through
the use of L<type constraints|/type/Signature#Type_constraints>. The
C<::?CLASS> variable can be used to provide the class name at compile
time, combined with either C<:U> (for class methods) or C<:D> (for
instance methods).

=begin code
class Pizza {
    has $!radius = 42;
    has @.ingredients;

    # class method: construct from a list of ingredients
    method from-ingredients(::?CLASS:U $pizza: @ingredients) {
        $pizza.new( ingredients => @ingredients );
    }

    # instance method
    method get-radius(::?CLASS:D:) { $!radius }
}
my $p = Pizza.from-ingredients: <cheese pepperoni vegetables>;
say $p.ingredients;     # OUTPUT: «[cheese pepperoni vegetables]␤»
say $p.get-radius;      # OUTPUT: «42␤»
say Pizza.get-radius;   # This will fail.
CATCH { default { put .^name ~ ":\n" ~ .Str } };
# OUTPUT: «X::Parameter::InvalidConcreteness:␤
#          Invocant of method 'get-radius' must be
#          an object instance of type 'Pizza',
#          not a type object of type 'Pizza'.
#          Did you forget a '.new'?»
=end code

A method can be both a class and object method by using the
L<multi|/syntax/multi> declarator:

=begin code
class C {
    multi method f(::?CLASS:U:) { say "class method"  }
    multi method f(::?CLASS:D:) { say "object method" }
}
C.f;       # OUTPUT: «class method␤»
C.new.f;   # OUTPUT: «object method␤»
=end code

=head2 X<C<self>>

Inside a method, the term C<self> is available and bound to the invocant
object. C<self> can be used to call further methods on the invocant,
including constructors:

=begin code
class Box {
  has $.data;

  method make-new-box-from() {
      self.new: data => $!data;
  }
}
=end code

C<self> can be used in class or instance methods as well, though beware
of trying to invoke one type of method from the other:

=begin code
class C {
    method g()            { 42     }
    method f(::?CLASS:U:) { self.g }
    method d(::?CLASS:D:) { self.f }
}
C.f;        # OUTPUT: «42␤»
C.new.d;    # This will fail.
CATCH { default { put .^name ~ ":\n" ~ .Str } };
# OUTPUT: «X::Parameter::InvalidConcreteness:␤
#          Invocant of method 'f' must be a type object of type 'C',
#          not an object instance of type 'C'.  Did you forget a 'multi'?»
=end code

C<self> can also be used with attributes, as long as they have an accessor.
C<self.a> will call the accessor for an attribute declared as C<has $.a>.
However, there is a difference between C<self.a> and C<$.a>, since the latter
will itemize; C<$.a> will be equivalent to C<self.a.item> or C<$(self.a)>.

=begin code
class A {
    has Int @.numbers;
    has $.x = (1, 2, 3);

    method show-diff() { .say for self.x; .say for $.x }

    method twice  { self.times: 2 }
    method thrice { $.times: 3    }

    method times($val = 1) { @!numbers.map(* * $val).list }
};

my $obj = A.new(numbers => [1, 2, 3]);
$obj.show-diff;   # OUTPUT: «1␤2␤3␤(1 2 3)␤»
say $obj.twice;   # OUTPUT: «(2 4 6)␤»
say $obj.thrice;  # OUTPUT: «(3 6 9)␤»
=end code


The colon-syntax for method arguments is supported for method calls
using either C<self> or the shortcut, as illustrated with the methods
C<twice> and C<thrice> in the example above.

Note that if the relevant methods C<bless>, C<CREATE> of L<Mu|/type/Mu>
are not overloaded, C<self> will point to the type object in those methods.

On the other hand, the submethods C<BUILD> and C<TWEAK> are called on instances,
in different stages of initialization. Submethods of the same name from
subclasses have not yet run, so you should not rely on potentially virtual
method calls inside these methods.

X<|Private methods>
=head2 Private methods

Methods with an exclamation mark C<!> before the method name are not callable
from anywhere outside the defining class; such methods are private in the sense
that they are not visible from outside the class that declares them. Private
methods are invoked with an exclamation mark instead of a dot:

=begin code
class FunMath {
    has $.value is required;
    method !do-subtraction( $num ) {
        if $num ~~ Str {
            return $!value + (-1 * $num.chars);
        }
        return $!value + (-1 * $num);
    }
    method minus( $minuend: $subtrahend ) {
        # invoking the private method on the explicit invocant
        $minuend!do-subtraction($subtrahend);
    }
}
my $five = FunMath.new(value => 5);
say $five.minus(6);         # OUTPUT: «-1␤»

say $five.do-subtraction(6);
CATCH { default { put .^name ~ ":\n" ~ .Str } }
# OUTPUT: «X::Method::NotFound:
# No such method 'do-subtraction' for invocant of type
# 'FunMath'. Did you mean '!do-subtraction'?␤»
=end code

Private methods are not inherited by subclasses.

X<|Submethods>
=head2 Submethods

Submethods are public methods that will not be inherited by subclasses. The
name stems from the fact that they are semantically similar to subroutines.

Submethods are useful for object construction and destruction tasks, as well
as for tasks that are so specific to a certain type that subtypes would
certainly have to override them.

For example, the L<default method new|/type/Mu#method_new> calls submethod
C<BUILD> on each class in an L<inheritance|#Inheritance> chain:

=begin code
class Point2D {
    has $.x;
    has $.y;

    submethod BUILD(:$!x, :$!y) {
        say "Initializing Point2D";
    }
}

class InvertiblePoint2D is Point2D {
    submethod BUILD() {
        say "Initializing InvertiblePoint2D";
    }
    method invert {
        self.new(x => - $.x, y => - $.y);
    }
}

say InvertiblePoint2D.new(x => 1, y => 2);
# OUTPUT: «Initializing Point2D␤»
# OUTPUT: «Initializing InvertiblePoint2D␤»
# OUTPUT: «InvertiblePoint2D.new(x => 1, y => 2)␤»
=end code

See also: L<Object construction|#Object_construction>.

=head2 Inheritance

Classes can have I<parent classes>.

=for code :preamble<class Parent1 {}; class Parent2 {};>
class Child is Parent1 is Parent2 { }

X<|MRO>
If a method is called on the child class, and the child class does not
provide that method, the method of that name in one of the parent classes is
invoked instead, if it exists. The order in which parent classes are
consulted is called the I<method resolution order> (MRO). Raku uses the
L<C3 method resolution order|https://en.wikipedia.org/wiki/C3_linearization>.
You can ask a type for its MRO through a call to its metaclass:

=for code
say List.^mro;      # ((List) (Cool) (Any) (Mu))

If a class does not specify a parent class, L<Any|/type/Any> is assumed
by default. All classes directly or indirectly derive from L<Mu|/type/Mu>,
the root of the type hierarchy.

All calls to public methods are "virtual" in the C++ sense, which means that
the actual type of an object determines which method to call, not the
declared type:

=begin code
class Parent {
    method frob {
        say "the parent class frobs"
    }
}

class Child is Parent {
    method frob {
        say "the child's somewhat more fancy frob is called"
    }
}

my Parent $test;
$test = Child.new;
$test.frob;          # calls the frob method of Child rather than Parent
# OUTPUT: «the child's somewhat more fancy frob is called␤»
=end code

If you want to explicitly call the parent method on a child object,
refer to its full name in the parent namespace:

=begin code :preamble<my $test>
$test.Parent::frob;  # calls the frob method of Parent
# OUTPUT: «the parent class frobs␤»
=end code

X<|delegation (trait handles)>
=head2 Delegation

Delegation is a technique whereby a member of an object (the I«delegatee») is
evaluated in the context of another original object (the I«delegator»). In other
words, all method calls on the delegator are I«delegated» to the delegatee.

In Raku, delegation is specified by applying the L«handles|/language/typesystem#trait_handles»
trait to an attribute. The arguments provided to the trait specify the methods
the current object and the delegatee object will have in common. Instead of a
list of method names, a C<Pair> (for renaming), a list of C<Pairs>, a C<Regex>
or a C<Whatever> can be provided.

=begin code
class Book {
    has Str  $.title;
    has Str  $.author;
    has Str  $.language;
    has Cool $.publication;
}

class Product {
    has Book $.book handles('title', 'author', 'language', year => 'publication');
}

my $book = Book.new:
    :title<Dune>,
    :author('Frank Herbert'),
    :language<English>,
    :publication<1965>
;

given Product.new(:$book) {
    say .title;    # OUTPUT: «Dune␤»
    say .author;   # OUTPUT: «Frank Herbert␤»
    say .language; # OUTPUT: «English␤»
    say .year;     # OUTPUT: «1965␤»
}
=end code

In the example above, the class C«Product» defines the attribute C«$.book»
and mark it with the C«handles» trait to specify the methods that will be
forwarded to the class C«Book» whenever they're invoked on an instance
object of the C«Product» class. There are a few things to notice here:

=item We didn't write any methods inside the C«Product» class that we invoked
in its instance object. Instead, we instructed the class to delegate a call to
any those methods to the C«Book» class.

=item We've specified the method names C«title», C«author», and C«language»
as they appear in the C«Book» class. On the other hand, we've renamed
the C«publication» method to C«year» by providing the appropriate C«Pair».

Delegation can be used as an alternative to inheritance by delegating
to the parent class and not inheriting all of its methods. For example, the
following C«Queue» class delegates several methods proper of queues
to the L«Array|/type/Array» class while also providing a preferred interface for
a few of those methods (e.g., C«enqueue» for C«push»):

=begin code
class Queue {
    has @!q handles(
        enqueue => 'push', dequeue => 'shift',
        'push', 'shift', 'head', 'tail', 'elems', 'splice'
    );

    method gist {
        '[' ~ @!q.join(', ') ~ ']'
    }
}

my Queue $q .= new;
$q.enqueue($_) for 1..5;
$q.push(6);
say $q.shift;                  # OUTPUT: «1␤»
say $q.dequeue while $q.elems; # OUTPUT: «2␤3␤4␤5␤6␤»

$q.enqueue($_) for <Perl Python Raku Ruby>;
say $q.head;                   # OUTPUT: «Perl␤»
say $q.tail;                   # OUTPUT: «Ruby␤»
say $q;                        # OUTPUT: «[Perl, Python, Raku, Ruby]␤»
$q.dequeue while $q.elems;
say $q;                        # OUTPUT: «[]␤»
=end code

X<|new (method)>
=head2 Object construction

Objects are generally created through method calls, either on the type
object or on another object of the same type.

Class L<Mu|/type/Mu> provides a constructor method called
L<new|/routine/new>, which takes named
L<arguments|/language/functions#Arguments> and uses them to initialize public
attributes.

=begin code
class Point {
    has $.x;
    has $.y;
}
my $p = Point.new( x => 5, y => 2);
#             ^^^ inherited from class Mu
say "x: ", $p.x;
say "y: ", $p.y;
# OUTPUT: «x: 5␤»
# OUTPUT: «y: 2␤»
=end code

C<Mu.new> calls method L<bless|/routine/bless> on its invocant, passing all
the named L<arguments|/language/functions#Arguments>. C<bless> creates the new
object, and then walks all subclasses in reverse method resolution order
(i.e. from L<Mu|/type/Mu> to most derived classes). In each class C<bless>
executes the following steps in the order given here:

=item It checks for the existence of a method named C<BUILD>. If the method
exists, the method is called with all the named arguments it received (from the
C<new> method).

=item If no C<BUILD> method was found, the public attributes from this class
are initialized from named arguments of the same name.

=begin item
All attributes that have not been touched in any of the previous steps have
their default values applied:

C<has $.attribute = 'default value';>
=end item

=begin item
X<|TWEAK>
C<TWEAK> is called should it exist. It will receive the same arguments
C<BUILD> receives.
=end item

This object construction scheme has several implications:

=begin item
Named arguments to the default C<new> constructor (inherited from C<Mu>) can
correspond directly to public attributes of any of the classes in the method
resolution order, or to any named parameter of any C<BUILD> or C<TWEAK>
submethod.
=end item

=begin item
Custom C<BUILD> methods should always be submethods, otherwise they are
inherited to subclasses and prevent default attribute initialization (item two
in the above list) should the subclass not have its own C<BUILD> method.
=end item

=begin item
C<BUILD> may set an attribute, but it does not have access to the contents of
the attribute declared as its default as they are only applied later.
C<TWEAK> on the other hand is called after default values have been
applied and will thus find the attributes initialized. So it can be used to
check things or modify attributes after object construction:

=begin code
class RectangleWithCachedArea {
    has ($.x1, $.x2, $.y1, $.y2);
    has $.area;
    submethod TWEAK() {
        $!area = abs( ($!x2 - $!x1) * ( $!y2 - $!y1) );
    }
}

say RectangleWithCachedArea.new( x2 => 5, x1 => 1, y2 => 1, y1 => 0).area;
# OUTPUT: «4␤»
=end code
=end item

=begin item
Since passing arguments to a routine binds the arguments to the parameters,
one can simplify BUILD methods by using the attribute as a parameter.

A class using ordinary binding in the C<BUILD> method:
=begin code
class Point {
    has $.x;
    has $.y;

    submethod BUILD(:$x, :$y) {
        $!x := $x;
        $!y := $y;
    }
}
my $p1 = Point.new( x => 10, y => 5 );
=end code

The following C<BUILD> method is equivalent to the above:
=begin code :preamble<has $.x; has $.y>
submethod BUILD(:$!x, :$!y) {
    # Nothing to do here anymore, the signature binding
    # does all the work for us.
}
=end code
=end item

=begin item
In order to use default values together with a `BUILD()` method one can't use
parameter binding of attributes, as that will always touch the attribute and
thus prevent the automatic assignment of default values (step three in the
above list). Instead one would need to conditionally assign the value:

=begin code
class A {
    has $.attr = 'default';
    submethod BUILD(:$attr) {
        $!attr = $attr if defined $attr;
    }
}
say A.new(attr => 'passed').raku;
say A.new().raku;
# OUTPUT: «A.new(attr => "passed")␤»
# OUTPUT: «A.new(attr => "default")␤»
=end code

It's simpler to set a default value of the `BUILD` parameter instead though:

=begin code
class A {
    has $.attr;
    submethod BUILD(:$!attr = 'default') {}
}
=end code
=end item

=begin item
Be careful when using parameter binding of attributes when the attribute has a
special type requirement such as an C<Int> type. If C<new> is called without
this parameter, then a default of C<Any> will be assigned, which will cause a
type error. The easy fix is to add a default value to the C<BUILD> parameter.

=begin code
class A {
    has Int $.attr;
    submethod BUILD(:$!attr = 0) {}
}
say A.new(attr => 1).raku;
say A.new().raku;
# OUTPUT: «A.new(attr => 1)␤»
# OUTPUT: «A.new(attr => 0)␤»
=end code
=end item

=begin item
C<BUILD> allows to create aliases for attribute initialization:

=begin code
class EncodedBuffer {
    has $.enc;
    has $.data;

    submethod BUILD(:encoding(:$!enc), :$!data) { }
}
my $b1 = EncodedBuffer.new( encoding => 'UTF-8', data => [64, 65] );
my $b2 = EncodedBuffer.new( enc      => 'UTF-8', data => [64, 65] );
#  both enc and encoding are allowed now
=end code
=end item

=begin item
Note that the name C<new> is not special in Raku. It is merely a common
convention, one that is followed quite thoroughly in
L<most Raku classes|/routine/new>. You can call C<bless> from any method, or
use C<CREATE> to fiddle around with low-level workings.
=end item

=begin item
If you want a constructor that accepts positional arguments, you must write
your own C<new> method:

=begin code
class Point {
    has $.x;
    has $.y;
    method new($x, $y) {
        self.bless(:$x, :$y);
    }
}
=end code

Do note, however, that C<new> is a normal method and not involved in any of the
construction process of C<bless>. So any logic placed in the C<new> method will
not be called when using a different C<new> method or a C<new> of a subclass.

=begin code
class Vector {
    has $.x;
    has $.y;
    has $.length;
    method new($x, $y) {
        self.bless(:$x, :$y, length => sqrt($x**2 * $y**2));
    }
}

class NamedVector is Vector {
    has $.name;
    method new($name, $x, $y) {
        self.bless(:$name, :$x, :$y);
    }
}

my $v = Vector.new: 2, 3;
say $v.length; # OUTPUT: «6␤»

my $f = NamedVector.new: 'Francis', 3, 5;
say $f.length; # OUTPUT: «(Any)␤»
=end code

=end item

Here is an example where we I<enrich> the C<Str> class with an
auto-incrementing ID:

=begin code
class Str-with-ID is Str {
    my $counter = 0;
    has Int $.ID  is rw = 0;

    multi method new( $str ) {
        self.bless( value => $str );
    }
    submethod BUILD( :$!ID = $counter++ ) {}
}

say Str-with-ID.new("1.1,2e2").ID;                  # OUTPUT: «0␤»
my $enriched-str = Str-with-ID.new("3,4");
say "$enriched-str, {$enriched-str.^name}, {$enriched-str.ID}";
# OUTPUT: «3,4, Str-with-ID, 1␤»
=end code

We create a custom C<new> since we want to be able to be able to initialize
our new class with a bare string. C<bless> will call C<Str.BUILD> which will
I<capture> the value it's looking for, the pair C«value => $str» and
initialize itself. But we have to also initialize the properties of the
subclass, which is why within C<BUILD> we initialize C<$.ID>. As seen in the
output, the objects will be correctly initialized with an ID and can be used
just like a normal C<Str>.

=head2 Object cloning

The cloning is done using the L<clone|/routine/clone> method available on all
objects, which shallow-clones both public and private attributes. New values for
I<public> attributes can be supplied as named arguments.

=begin code
class Foo {
    has $.foo = 42;
    has $.bar = 100;
}

my $o1 = Foo.new;
my $o2 = $o1.clone: :bar(5000);
say $o1; # Foo.new(foo => 42, bar => 100)
say $o2; # Foo.new(foo => 42, bar => 5000)
=end code

See document for L<clone|/routine/clone> for details on how non-scalar
attributes get cloned, as well as examples of implementing your own custom clone
methods.

=head1 X<Roles|declarator,role>

Roles are a collection of attributes and methods; however, unlike classes, roles
are meant for describing only parts of an object's behavior; this is why, in
general, roles are intended to be I<mixed in> classes and objects. In general,
classes are meant for managing objects and roles are meant for managing behavior
and code reuse within objects.

X<|does>
Roles use the keyword C<role> preceding the name of the role that is
declared. Roles are mixed in using the C<does> keyword preceding the name of
the role that is mixed in.

Roles can also be mixed into a class using C<is>. However, the semantics of
C<is> with a role are quite different from those offered by C<does>. With C<is>,
a class is punned from the role, and then inherited from. Thus, there is no
flattening composition, and none of the safeties which C<does> provides.

=begin code
constant ⲧ = " " xx 4; #Just a ⲧab
role Notable {
    has Str $.notes is rw;

    multi method notes() { "$!notes\n" };
    multi method notes( Str $note ) { $!notes ~= "$note\n" ~ ⲧ };

}

class Journey does Notable {
    has $.origin;
    has $.destination;
    has @.travelers;

    method Str { "⤷ $!origin\n" ~ ⲧ ~ self.notes() ~ "$!destination ⤶\n" };
}

my $trip = Journey.new( :origin<Here>, :destination<There>,
                        travelers => <þor Freya> );

$trip.notes("First steps");
notes $trip: "Almost there";
print $trip;
# OUTPUT:
#⤷ Here
#       First steps
#       Almost there
#
#There ⤶
=end code

Roles are immutable as soon as the compiler parses the closing curly brace
of the role declaration.

=head2 Applying roles

Role application differs significantly from class inheritance. When a role
is applied to a class, the methods of that role are copied into the class.
If multiple roles are applied to the same class, conflicts (e.g.
attributes or non-multi methods of the same name) cause a compile-time error,
which can be solved by providing a method of the same name in the class.

This is much safer than multiple inheritance, where conflicts are never
detected by the compiler, but are instead resolved to the superclass
that appears earlier in the method resolution order, which might not
be what the programmer wanted.

For example, if you've discovered an efficient method to ride cows, and are
trying to market it as a new form of popular transportation, you might have
a class C<Bull>, for all the bulls you keep around the house, and a class
C<Automobile>, for things that you can drive.

=begin code
class Bull {
    has Bool $.castrated = False;
    method steer {
        # Turn your bull into a steer
        $!castrated = True;
        return self;
    }
}
class Automobile {
    has $.direction;
    method steer($!direction) { }
}
class Taurus is Bull is Automobile { }

my $t = Taurus.new;
say $t.steer;
# OUTPUT: «Taurus.new(castrated => Bool::True, direction => Any)␤»
=end code

With this setup, your poor customers will find themselves unable to turn
their Taurus and you won't be able to make more of your product! In this
case, it may have been better to use roles:

=begin code :skip-test<illustrates error>
role Bull-Like {
    has Bool $.castrated = False;
    method steer {
        # Turn your bull into a steer
        $!castrated = True;
        return self;
    }
}
role Steerable {
    has Real $.direction;
    method steer(Real $d = 0) {
        $!direction += $d;
    }
}
class Taurus does Bull-Like does Steerable { }
=end code

This code will die with something like:

=begin code :lang<text>
===SORRY!===
Method 'steer' must be resolved by class Taurus because it exists in
multiple roles (Steerable, Bull-Like)
=end code

This check will save you a lot of headaches:

=begin code :preamble<role Bull-Like{}; role Steerable{};>
class Taurus does Bull-Like does Steerable {
    method steer($direction?) {
        self.Steerable::steer($direction)
    }
}
=end code

When a role is applied to a second role, the actual application is delayed
until the second role is applied to a class, at which point both roles are
applied to the class. Thus

=begin code
role R1 {
    # methods here
}
role R2 does R1 {
    # methods here
}
class C does R2 { }
=end code

produces the same class C<C> as

=begin code
role R1 {
    # methods here
}
role R2 {
    # methods here
}
class C does R1 does R2 { }
=end code

=head2 Stubs

When a role contains a stubbed method, that is, a method whose code is limited
to C<...>, a non-stubbed version of a method of the same name must be supplied
at the time the role is applied to a class. This allows you to create roles that
act as abstract interfaces.

=begin code :skip-test<illustrates error>
role AbstractSerializable {
    method serialize() { ... }        # literal ... here marks the
                                      # method as a stub
}

# the following is a compile time error, for example
#        Method 'serialize' must be implemented by Point because
#        it's required by a role

class APoint does AbstractSerializable {
    has $.x;
    has $.y;
}

# this works:
class SPoint does AbstractSerializable {
    has $.x;
    has $.y;
    method serialize() { "p($.x, $.y)" }
}
=end code

The implementation of the stubbed method may also be provided by another
role.

=head2 Inheritance

Roles cannot inherit from classes, but they may I<carry> classes, causing
any class which does that role to inherit from the carried classes.
So if you write:

=begin code
role A is Exception { }
class X::Ouch does A { }
X::Ouch.^parents.say # OUTPUT: «((Exception))␤»
=end code

then C<X::Ouch> will inherit directly from Exception, as we can see above
by listing its parents.

As they do not use what can properly be called inheritance, roles are not part
of the class hierarchy. Roles are listed with the C<.^roles> metamethod
instead, which uses C<transitive> as flag for including all levels or just the
first one. Despite this, a class or instance may still be tested with
smartmatches or type constraints to see if it does a role.

=begin code
role F { }
class G does F { }
G.^roles.say;                    # OUTPUT: «((F))␤»
role Ur {}
role Ar does Ur {}
class Whim does Ar {}; Whim.^roles(:!transitive).say;   # OUTPUT: «((Ar))␤»
say G ~~ F;                      # OUTPUT: «True␤»
multi a (F $a) { "F".say }
multi a ($a)   { "not F".say }
a(G);                            # OUTPUT: «F␤»
=end code

=head2 Pecking order

A method defined directly in a class will always override definitions from
applied roles or from inherited classes. If no such definition exists, methods
from roles override methods inherited from classes. This happens both when
said class was brought in by a role, and also when said class was inherited
directly.

=begin code
role M {
  method f { say "I am in role M" }
}

class A {
  method f { say "I am in class A" }
}

class B is A does M {
  method f { say "I am in class B" }
}

class C is A does M { }

B.new.f; # OUTPUT: «I am in class B␤»
C.new.f; # OUTPUT: «I am in role M␤»
=end code

Note that each candidate for a multi-method is its own method. In this case,
the above only applies if two such candidates have the same signature.
Otherwise, there is no conflict, and the candidate is just added to the
multi-method.

=head2 Automatic role punning

Any attempt to directly instantiate a role or use it as a type object
will automatically create a class with the same name as the role,
making it possible to transparently use a role as if it were a class.

=begin code
role Point {
    has $.x;
    has $.y;
    method abs { sqrt($.x * $.x + $.y * $.y) }
    method dimensions { 2 }
}
say Point.new(x => 6, y => 8).abs; # OUTPUT: «10␤»
say Point.dimensions;              # OUTPUT: «2␤»
=end code

We call this automatic creation of classes I<punning>, and the generated class
a I<pun>.

Punning is not caused by most L<metaprogramming|/language/mop> constructs,
however, as those are sometimes used to work directly with roles.

X<|Parameterized Roles>
=head2 Parameterized roles

Roles can be parameterized, by giving them a signature in square brackets:

=begin code
role BinaryTree[::Type] {
    has BinaryTree[Type] $.left;
    has BinaryTree[Type] $.right;
    has Type $.node;

    method visit-preorder(&cb) {
        cb $.node;
        for $.left, $.right -> $branch {
            $branch.visit-preorder(&cb) if defined $branch;
        }
    }
    method visit-postorder(&cb) {
        for $.left, $.right -> $branch {
            $branch.visit-postorder(&cb) if defined $branch;
        }
        cb $.node;
    }
    method new-from-list(::?CLASS:U: *@el) {
        my $middle-index = @el.elems div 2;
        my @left         = @el[0 .. $middle-index - 1];
        my $middle       = @el[$middle-index];
        my @right        = @el[$middle-index + 1 .. *];
        self.new(
            node    => $middle,
            left    => @left  ?? self.new-from-list(@left)  !! self,
            right   => @right ?? self.new-from-list(@right) !! self,
        );
    }
}

my $t = BinaryTree[Int].new-from-list(4, 5, 6);
$t.visit-preorder(&say);    # OUTPUT: «5␤4␤6␤»
$t.visit-postorder(&say);   # OUTPUT: «4␤6␤5␤»
=end code

Here the signature consists only of a type capture, but any signature will do:

=begin code
enum Severity <debug info warn error critical>;

role Logging[$filehandle = $*ERR] {
    method log(Severity $sev, $message) {
        $filehandle.print("[{uc $sev}] $message\n");
    }
}

Logging[$*OUT].log(debug, 'here we go'); # OUTPUT: «[DEBUG] here we go␤»
=end code

You can have multiple roles of the same name, but with different signatures;
the normal rules of multi dispatch apply for choosing multi candidates.

X<|but>
=head2 X<Mixins> of roles

Roles can be mixed into objects. A role's given attributes and methods will be
added to the methods and attributes the object already has. Multiple mixins and
anonymous roles are supported.

=begin code
role R { method Str() {'hidden!'} };
my $i = 2 but R;
sub f(\bound){ put bound };
f($i); # OUTPUT: «hidden!␤»
my @positional := <a b> but R;
say @positional.^name; # OUTPUT: «List+{R}␤»
=end code

Note that the object got the role mixed in, not the object's class or the
container. Thus, @-sigiled containers will require binding to make the role
stick as is shown in the example with C<@positional>. Some operators will return
a new value, which effectively strips the mixin from the result. That is why it
might be more clear to mix in the role in the declaration of the variable using
C<does>:

=begin code
role R {};
my @positional does R = <a b>;
say @positional.^name; # OUTPUT: «Array+{R}␤»
=end code

The operator C<infix:<but>> is narrower than the list constructor. When
providing a list of roles to mix in, always use parentheses.

=for code
role R1 { method m {} }
role R2 { method n {} }
my $a = 1 but R1,R2; # R2 is in sink context, issues a WARNING
say $a.^name;
# OUTPUT: «Int+{R1}␤»
my $all-roles = 1 but (R1,R2);
say $all-roles.^name; # OUTPUT: «Int+{R1,R2}␤»

If the role supplies exactly one attribute, an initializer can be passed in
parentheses:

=begin code
role Named {
    has $.name;
}
my $hero = 1.Rat but Named('Remy');
say $hero.name;     # OUTPUT: «Remy␤»
=end code

Mixins can be used at any point in your object's life.

=begin code
# A counter for Table of Contents
role TOC-Counter {
    has Int @!counters is default(0);
    method Str() { @!counters.join: '.' }
    method inc($level) {
        @!counters[$level - 1]++;
        @!counters.splice($level);
        self
    }
}

my Num $toc-counter = NaN;     # don't do math with Not A Number
say $toc-counter;              # OUTPUT: «NaN␤»
$toc-counter does TOC-Counter; # now we mix the role in
$toc-counter.inc(1).inc(2).inc(2).inc(1).inc(2).inc(2).inc(3).inc(3);
put $toc-counter / 1;          # OUTPUT: «NaN␤» (because that's numerical context)
put $toc-counter;              # OUTPUT: «2.2.2␤» (put will call TOC-Counter::Str)
=end code

Roles can be anonymous.

=begin code
my %seen of Int is default(0 but role :: { method Str() {'NULL'} });
say %seen<not-there>;          # OUTPUT: «NULL␤»
say %seen<not-there>.defined;  # OUTPUT: «True␤» (0 may be False but is well defined)
say Int.new(%seen<not-there>); # OUTPUT: «0␤»
=end code

=head1 Metaobject programming and introspection

Raku has a metaobject system, which means that the behavior of objects,
classes, roles, grammars, enums, etc. are themselves controlled by other
objects; those objects are called I<metaobjects>. Metaobjects are, like
ordinary objects, instances of classes, in this case we call them I<metaclasses>.

For each object or class you can get the metaobject by calling C<.HOW> on it.
Note that although this looks like a method call, it works more like a macro.

So, what can you do with the metaobject? For one you can check if two
objects have the same metaclass by comparing them for equality:

=begin code
say 1.HOW ===   2.HOW;      # OUTPUT: «True␤»
say 1.HOW === Int.HOW;      # OUTPUT: «True␤»
say 1.HOW === Num.HOW;      # OUTPUT: «False␤»
=end code

Raku uses the word I<HOW> (Higher Order Workings) to refer to the metaobject
system. Thus it should be no surprise that in Rakudo, the class name of the
metaclass that controls class behavior is called C<Perl6::Metamodel::ClassHOW>.
For each class there is one instance of C<Perl6::Metamodel::ClassHOW>.

But of course the metamodel does much more for you. For example, it allows
you to introspect objects and classes. The calling convention for methods on
metaobjects is to call the method on the metaobject and pass in the object
of interest as first argument to the object. So to get the name of the class
of an object, you could write:

=begin code
my $object = 1;
my $metaobject = 1.HOW;
say $metaobject.name($object);      # OUTPUT: «Int␤»

# or shorter:
say 1.HOW.name(1);                  # OUTPUT: «Int␤»
=end code

(The motivation is that Raku also wants to allow a more prototype-based
object system, where it's not necessary to create a new metaobject for
every type).

There's a shortcut to keep from using the same object twice:

=begin code
say 1.^name;                        # OUTPUT: «Int␤»
# same as
say 1.HOW.name(1);                  # OUTPUT: «Int␤»
=end code

See L<Metamodel::ClassHOW|/type/Metamodel::ClassHOW> for documentation on the
metaclass of C<class> and also the L<general documentation on the metaobject
protocol|/language/mop>.

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
