Raku By Example
View me onGitHub
## Classes
#---------

class Point {
    has Str $!name;   # twigil `!` declares a private attribute.
    has Int $.x;      # twigil `.` declares an outwardly available attribute 
    has Int $.y;      # which is equivalent to a private attribute with
                      # a read-only accesor generated automatically.

    # this is a private method accesible only within the class. Note
    # the `!` in front of its name.
    method !to-center {
        sqrt($!x ** 2 + $!y ** 2); # use the `!` to access/assign to 
                                   # attributes internally
    }

    # this is a public method accesible
    # from outside the class.
    method distance-from-center {
        self!to-center;           # private methods must be invoked using
                                  # `!` on `self` or explicit invocant.
    }

    # this method is also public. 
    method set-name(Str $name) {
        $!name = $name;
    }

}

# Instantiate a class with the default constructor `new`
# by providing named arguments.
my $point = Point.new(x => 3, y => 4);

# Private attributes cannot be set with `new` so here it's done after the 
# object construction. Nonetheless, this can be achieved during object
# construction by different mechanisms.
$point.set-name('Point 1');

# Calling a method on the instance object is done with dot notation.
say $point.distance-from-center;

# As mentioned previously, free accesor methods are provided whenever
# attributes are declared with the `.` twigil. So:
say $point.x;
say $point.y;


class Circle {
    has Point $.center;
    has Int $.radius = 1; # attributes can have default values

    method area {
        pi * $!radius ** 2;
    }
}

my $circle = Circle.new(
    center => Point.new(x => 5, y => 10),
    radius => 50
);

say $circle.area; # 7853.98...

## Inheritance - achieved through the use of the keyword `is`.
##------------

class Mammal {
    has $.name;
    has $.nourishment-type = "milk from mother's mammary glands";

    method sound {
        say "mammal makes sound";
    }
    # And more methods, submethods, attributes common to mammals
}


## Roles - a role is declared with `role` and applied with the keyword `does`.
##-------
role Pet {
    method is-companion { True }

    # And other methods that apply to Pets
}

role Shepherd {
    method does-herd { True }

    # And other methods that apply to Shepherds
}

## Inheritance and roles: Application
##-----------------------

class Dog is Mammal does Pet does Shepherd {
    has $.name = 'Doggy';

    # sound specific to dogs
    method sound {
        say "woof woof";
    }
    # And more methods, submethods, attributes common to Dogs
}

class Cat is Mammal does Pet {
    has $.name = 'Cattie';

    # sound specific to cats
    method sound {
        say "meow";
    }
    # And more methods, submethods, attributes common to Cats
}

my $cornie = Dog.new(name => 'Cornie');
say $cornie.name;   # 'Cornie'
$cornie.sound;      # 'woof woof'

my $prosia = Cat.new(name => 'Prosia');
say $prosia.name;   # 'Prosia'
$prosia.sound;      # 'meow'

if $cornie.is-companion {
    my $output = $cornie.name ~ " is a pet.";
    $output   ~= " And is herding the sheep!" if $cornie.does-herd;

    say $output;
}

if $prosia.is-companion {
    say $prosia.name, " is a pet";
}