Team LiB   Previous Section   Next Section

4.5 Classes and Objects

Class syntax won't really be decided until Apocalypse 12, so this section is the most sketchy and likely to change of any in the chapter. Rather than roll out a lengthy speculation, we focus on the parts that are relatively certain.

Class declarations have two forms. The most basic is a class declaration statement, followed by the code that defines the class. There can be only one class or module declaration statement in a file. All code that follows is defined in the Heart::Gold namespace:

class Heart::Gold;
# class definition follows
...

The other form wraps the declaration and definition into a block. Everything within the class's block is defined in the namespace of the class. You can have as many of these as you like in a file, and embed one class within the block of another:

class Heart::Gold {
    # class definition enclosed
    ...
}

To create a new object from a class, simply call its new method. A default new method is provided in the universal base class Object:

$ship = Heart::Gold.new(length => 150);

4.5.1 Attributes

Attributes are the data at the core of a class. They are commonly known as instance variables, data members, or instance attributes. They're declared with the has keyword, and always have a "." after the sigil:

class Heart::Gold {
    has $.height;
    has $.length;
    has @.cargo;
    has %.crew;
    ...
}

Attributes also automatically generate their own accessor method with the same name as the attribute:

$obj.height(  ) # returns the value of $.height

By default, all attributes and their accessor methods are private to the class. If you want them to be accessible from outside the class, flag them with the is public trait:

has $.height is public;

4.5.2 Methods

Methods are similar to subroutines, but different enough to merit their own keyword, method. The most obvious differences are that they're always invoked on an object (or class), and they always pass their invocant (that is, the object or class on which they were invoked) as an implicit argument. The invocant is marked off from the other parameters in the list by a colon, as follows:

method initiate_drive ($self: $power, $tea) {
    ...
}

Methods topicalize their invocant, so it's always accessible as $_, even if the method doesn't include it in the parameter list or has no parameter list. This is particularly handy since any method called without an explicit object defaults to $_:

method shut_down (: $drive){
    if .safe {
        .powerdown($drive);
    }
    return .status;
}

Methods are public by default, but can be made private to the class with the is private trait:

method inaccessible is private ($self: $value) {
    ...
}

4.5.3 Inheritance

Any class can inherit methods from another class using the is keyword[13] in the class declaration.

[13] This is the same keyword as compile-time properties. The fact that a class inherits from some other class is really just a trait of the inheriting class.

Both public and private methods are inherited by the derived class, but only public methods are directly accessible in the derived class:

use Ship;
class Heart::Gold is Ship {
    ....
}

Inherited attributes are only accessible within the derived class through their accessor methods:

class Ship {
    has $.height;
    has $.length;
    ...
}

class Heart::Gold is Ship {
    method dimensions ($self:){
        print "$self.length  x $self.height \n";
    }
}

4.5.4 Lexically Scoped Classes

Classes in Perl 6 are first class entities with entries in the symbol table.[14]

[14] If you're curious, their sigil is ::, though it's never needed in code.

This means classes can be lexically scoped, just like variables or subroutines:

my class Infinite::Improbablity {
    ...
}

$drive = Infinite::Improbability.new(  );

A my-ed class works just like any other class, but is accessible only within the lexical scope where it's defined.

4.5.5 Anonymous Classes

You can also define anonymous classes and create objects from them:

$class = class {
   ...
}

$object = $class.new(  );

A class's block is a closure, just like every other block, so it has access to variables from its defining scope, no matter where it's actually used.

4.5.6 Subroutines in Classes

You can also define ordinary subroutines within a class. They cannot be invoked on an object with the $object.methodname syntax, will never pass an implicit invocant argument, and aren't inherited. They're mainly useful for utility code internal to the class:

class Answer::Young;

has $.answer;
...
sub is_valid ($value) {
    return 1 if 10 < $value < 42;
}
...
method set_answer (: $new) {
    $.answer = $new if is_valid($new);
}
    Team LiB   Previous Section   Next Section