=begin pod

=TITLE Object Orientation

=SUBTITLE Object Orientation in Perl 6

Perl 6 is an object oriented language at its core, even though it allows you
to write programs in other programming styles.

Perl 6 comes with a wealth of predefined types, which can be classified in
two categories: normal and I<native> types.

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

Everything that you can store in a variable is either a native value or an
object. That includes literals, types (type objects), code and containers.

=head1 Using Objects

You can use objects by calling methods on them. To call a method on an
expression, add a dot, followed by the method name:

=for code :allow<B L>
L<say> "abc"B<.L<uc>>;
# ABC

This calls the L<C<uc>|uc> method on C<"abc">, which is an object of type
L<C<Str>|Str>. If you need to supply arguments to the method, add
parentheses after the method name with the arguments inside the parentheses:

=for code :allow<B L>
my $formatted-text = "Fourscore and seven years ago...".L<indent>B<(8)>;

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

Multiple arguments simply require a comma between them:

=for code :allow<B L>
my @words = "Abe", "Lincoln";
@words.L<push>("said"B<,> $formatted-text.L<comb>(L</\w+/|/language/regexes>));

Another method call syntax separates the method name and the argument list
with a colon:

=for code :allow<B L>
say @words.L<join>: '--';
# Abe--Lincoln--said--Fourscore--and--seven--years--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 parens is
unambiguously a method call without an argument list:

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

Many operations that don't look like method calls (for example, smart
matching, or interpolating an object into a string) 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 :allow<L>
$*IN.L<nl-in> = "\r\n";

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

All objects support methods from class L<Mu>, which is the root of the
type hierarchy. In other words, all objects are derived from C<Mu>.

=head2 Type Objects

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

    my $int-type-obj = Int;

You can ask any object for its type object by calling the C<WHAT> method
(which is actually a macro in method form):

    my $int-type-obj = 1.WHAT;

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

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

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

=for code :allow<B L>
sub f($x) {
    if $xB<.L<isa>>(Int) {
        ...
    }
    ...
}

Subtype checking is done by smart-matching:

=for code :allow<B L>
if $type B<L<~~>> L<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.

    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:

    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

Attributes are variables that exist per instance of a class. They are where
the state of an object is stored. In Perl 6, all attributes are private.
They are typically declared using the C<has> declarator and the C<!> twigil.

    class Journey {
        has $!origin;
        has $!destination;
        has @!travellers;
        has $!notes;
    }

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

    class Journey {
        has $.origin;
        has $.destination;
        has @!travellers;
        has $.notes;
    }

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

    class Journey {
        has $.origin;
        has $.destination;
        has @!travellers;
        has $.notes is rw;
    }

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.

The above allows creation of C<Journey> objects without an origin or
destination. To change this you can provide a default value or make
sure that it is provided by marking it with L<is required>.

    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 @!travellers;
        has $.notes is rw;
    }

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 :allow<B L>
    # Create a new instance of the class.
    my $vacation = Journey.new(
        origin      L«=>» '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 the default constructor will only set attributes that have an
accessor method, but it can initialize read-only attributes.

=head2 Methods

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

    =begin code :allow<B L>
    class Journey {
        has $.origin;
        has $.destination;
        has @!travellers;
        has $.notes is rw;

        B<method> add_traveller($name) {
            if $name L<ne> L<any>(@!travellers) {
                L<push> @!travellers, $name;
            }
            else {
                L<warn> "$name is already going on the journey!";
            }
        }

        B<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 really, the C<.> twigil
declares a C<!> twigil and then additionally 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>. The first is always a simple
lookup of the attribute. It is cheap, and you know that it is the attribute
declared in this class. The latter is really a method call and thus it may
be overridden in a subclass. Only use C<$.origin> if you explicitly 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>

=head2 self

Inside a method, the term C<self> is available, which is bound to the
invocant, i.e.  the object that the method was called on. C<self> can be
used to call further methods on the invocant. Within methods, something like
C<$.origin> is the same thing as C<self.origin>.

=head2 Private Methods

Methods strictly for use inside the class and that are not to be called from
anywhere else are declared with an exclamation mark C<!> before the method
name. They are called with an exclamation mark instead of a dot:

    method !do-something-private($x) {
        ...
    }
    method public($x) {
        if self.precondition {
            self!do-something-private(2 * $x)
        }
    }

Private methods are not inherited to subclasses.

=head2 Submethods

A submethod is a public method that is not inherited to 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 must
certainly 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);
=end code

This produces the following output:

=begin code
Initializing Point2D
Initializing InvertiblePoint2D
InvertiblePoint2D.new(x => 1, y => 2)
=end code

See also: L<#Object Construction>.

=head2 Inheritance

Classes can have I<parent classes>.

=for code :allow<B L>
class Child B<L<is> Parent1 is Parent2> { }

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). Perl 6 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 meta class:

=for code :allow<B L>
say List<.^L<mro>>;      # List() Cool() Any() Mu()

If a class does not specify a parent class, L<Any> is assumed by default.
All classes directly or indirectly derive from L<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
    =end code

This produces the output:

    the child's somewhat more fancy frob is called

=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> provides a constructor method called L<new>, which takes named
arguments and uses them to initialize public attributes.

=for code :allow<B L>
class Point {
    has $.x;
    has $.y = 2 * $!x;
}
my $p = PointB<.L<new>>( x L«=>» 5, y => 2);
#             ^^^ inherited from class Mu
say "x: ", $p.x;
say "y: ", $p.y;

This outputs:

    x: 5
    y: 2

=for code :allow<B L>
my $p2 = PointB<.new>( x => 5 );
# the given value for x is used to calculate the right
# value for y.
say "x: ", $p.x;
say "y: ", $p.y;

This outputs:

    x: 5
    y: 10

C<Mu.new> calls method L<bless> on its invocant, passing all the named
arguments. C<bless> creates the new object and then calls method C<BUILDALL>
on it. C<BUILDALL> walks all subclasses in reverse method resolution order
(i.e. from L<Mu> to most derived classes) and in each class checks for
existence of a method named C<BUILD>. If it exists, it is called, again
passing all named arguments from method C<new> to it. If not, the public
attributes from this class are initialized from named arguments of the same
name. In either case, if neither C<BUILD> nor the default mechanism has
initialized the attribute, default values are applied (the C<2 * $!x> in the
example above).

Due to the nature of the default behavior of C<BUILDALL> and custom C<BUILD>
submethods, named arguments to the constructor C<new> derived from C<Mu> can
correspond directly to public attributes of any of the classes in the method
resolution order, or to any named parameter to any C<BUILD> submethod.

This object construction scheme has several implications for customized
constructors. First, custom C<BUILD> methods should always be submethods,
otherwise they break attribute initialization in subclasses. Second,
C<BUILD> submethods can be used to run custom code at object construction
time. They can also be used for creating aliases for attribute
initialization:

    =begin code :allow<B L>
    class EncodedBuffer {
        has $.enc;
        has $.data;

        submethod B<BUILD>(:encoding(:$enc), :$data) {
            $!enc  L<:=>  $enc;
            $!data := $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

Since passing arguments to a routine binds the arguments to the parameters,
a separate binding step is unnecessary if the attribute is used as a
parameter.  Hence the example above could also have been written as:

    =for code :allow<B L>
    submethod BUILD(:encoding(:$B<!>enc), :$B<!>data) {
        # nothing to do here anymore, the signature binding
        # does all the work for us.
    }

The third implication is that if you want a constructor that accepts
positional arguments, you must write your own C<new> method:

    =for code :allow<B L>
    class Point {
        has $.x;
        has $.y;
        method new($x, $y) {
            self.L<bless>(:$x, :$y);
        }
    }

However this is considered poor practice, because it makes correct
initialization of objects from subclasses harder.

Another thing to note is that the name C<new> is not special in Perl 6. It
is merely a common convention. You can call C<bless> from any method at all,
or use C<CREATE> to fiddle around with low-level workings.

Another pattern of hooking into object creation is by writing your own method
C<BUILDALL>. To make sure that initialization of superclasses works fine, you
need to C<callsame> to invoke the parent classes C<BUILDALL>.

=begin code
class MyClass {
    method BUILDALL(|) {
        # initial things here

        callsame;   # call the parent classes (or default) BUILDALL

        # you can do final checks here.
    }
}
=end code

=comment TODO: better example for BUILDALL overriding

=head2 Object Cloning

The C<Mu> parent class, from which all classes inherit, supplies a
method named L<clone> which is somewhat magical, in that it can copy
values from an instance's private attributes to create a new instance.
This cloning is shallow, in that it only binds attributes to
the same values they contained in the original instance; it does
not make copies of those contained values.

As with C<new>, one may provide initial values for public attributes.
These override values received from the original instance.  (See
the documentation for Mu's L<clone> for an example.)

Note that since C<clone> is not a C<submethod>, a class which provides
its own C<clone> method will replace the C<Mu> method.  There is no
automatic mechanism like C<BUILDALL> for cloning.  For example, if one
wished to make clone deeper for a particular class, one would will
probably want to use C<callwith> or C<nextwith> to push the deeper
copies to superclasses:

    class A {
        has $.a;
        #...
        method clone {
            nextwith(:a($.a.clone))
        }
    }

This works well for simple classes, but in some cases one might need
to follow C<BUILDALL>'s lead and work in reverse method resolution
order:

    class B is A {
        has $.b;
        #...
        method clone {
            my $obj = callsame;
            $obj.b = $!b.clone(:seed($obj.a.generate_seed));
            $obj
        }
    }

=head1 X<Roles|declarator,role>

Roles are in some ways similar to classes, in that they are a collection of
attributes and methods. They differ in that roles are also meant for
describing only parts of an object's behavior and in how roles are applied
to classes. Or to phrase it differently, classes are meant for managing
instances and roles are meant for managing behavior and code reuse.

    =begin code :allow<B L>
    use MONKEY-SEE-NO-EVAL;
    role Serializable {
        method serialize() {
            self.L<perl>; # very primitive serialization
        }
        method deserialize($buf) {
            L<EVAL> $buf; # reverse operation to .perl
        }
    }

    class Point B<does> Serializable {
        has $.x;
        has $.y;
    }
    my $p = Point.new(:x(1), :y(2));
    my $serialized = $p.serialize;      # method provided by the role
    my $clone-of-p = Point.deserialize($serialized);
    say $clone-of-p.x;      # 1
    =end code

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

=head2 Z<>Role Application

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 simply resolved to the superclass
that appears earlier in the method resolution order, which might or 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.

    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;
    $t.steer; # Castrates $t

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:

    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 { }

This code will die with something like:

    ===SORRY!===
    Method 'steer' must be resolved by class Taurus because it exists in
    multiple roles (Steerable, Bull-Like)

This check will save you and your customers a lot of headaches and you can
simply define your class instead as:

    class Taurus does Bull-Like does Steerable {
        method steer ($direction?) {
            self.Steerable::steer($direction?)
        }
    }

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

    role R1 {
        # methods here
    }
    role R2 does R1 {
        # methods here
    }
    class C does R2 { }

produces the same class C<C> as

    role R1 {
        # methods here
    }
    role R2 {
        # methods here
    }
    class C does R1 does R2 { }

=head2 Stubs

When a role contains a stubbed method, 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 :allow<B L>
    role AbstractSerializable {
        method serialize() { B<L<...>> }  # 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 is 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 Automatic Role Punning

Any attempt to instantiate (and many other kinds of usage) a role 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) }
}
say Point.new(x => 6, y => 8).abs;
=end code

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

=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);    # 5 \n 4 \n 6
$t.visit-postorder(&say);   # 4 \n 6 \n 5
=end code

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

=begin code
use v6;

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');        # [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.

=head2 Mixins of Roles

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

	role R { method Str() {'hidden!'} };
	my $i = 2 but R; 
	sub f(\bound){ put bound };
    f($i); # hidden!

Note that the object got the role mixed in, not the objects class or the 
container. Thus @-sigiled containers will require binding to make the role
stick. Some operators will return a new value, resulting in the mixin to be 
stripped as well.

Mixins can happen at any time of your objects life.

	# 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 maths with Not A Number
	say $toc-counter; # 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;          # NaN (because that's numerical context)
	put $toc-counter;              # 2.2.2 (put will call TOC-Counter::Str)

Roles can by anonymous.

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

=head1 Meta-Object Programming and Introspection

Perl 6 has a meta object system, which means that the behavior of objects,
classes, roles, grammars, enums etc. are themselves controlled by other
objects; those objects are called I<meta objects>. Meta objects are, like
ordinary objects, instances of classes, in this case we call them I<meta
classes>.

For each object or class you can get the meta object by calling C<.HOW> on
it. Note that although this looks like a method call, it is actually
special-cased in the compiler, so it is more like a macro.

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

    say 1.HOW ===   2.HOW;      # True
    say 1.HOW === Int.HOW;      # True
    say 1.HOW === Num.HOW;      # False

Perl 6 uses the word I<HOW>, Higher Order Workings, to refer to the meta
object system. Thus it should be no surprise that in Rakudo, the class name
of the meta class 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 meta model does much more for you. For example it allows
you to introspect objects and classes. The calling convention for methods on
meta objects is to call the method on the meta object 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:

    my $object = 1;
    my $metaobject = 1.HOW;
    say $metaobject.name($object);      # Int

    # or shorter:
    say 1.HOW.name(1);                  # Int

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

To get rid of using the same object twice, there is a shortcut:

    say 1.^name;                        # Int
    # same as
    say 1.HOW.name(1);                  # Int

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

=end pod
