6.2 Classes

     

Classes are the "cookie cutters" that build objects. Just as a module groups subroutines in a package, a class groups methods in a package. Classes can also contain subroutines, submethods , and multimethods. However, classes are significantly different from modules, primarily because they construct objects. Objects don't just define functionality, they also hold data. In Perl 5 objects were simply hashes (or arrays, or . . . ) bestowed with special powers by bless . Perl 6 objects can still be simple blessed data structures, but the default is now an object that hides the details of its internal representation ”a true opaque object.

6.2.1 Attributes

Attributes are the data at the core of an opaque object. Other languages have called them instance variables , data members , or instance attributes. Attributes are declared with the has keyword, and generally have a "." after the sigil:

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

Attributes aren't directly accessible outside the class, but inside the class they act just like ordinary variables:

 print $.length; $.length = 140; 

Attributes also automatically generate their own accessor method with the same name as the attribute. Accessor methods are accessible inside or outside the class. By default, accessors are read-only, but the is rw property marks an accessor as read/write.

 $value = $obj.height; # returns the value of $.height $obj.height = 90;     # sets the value of $.height 

6.2.2 Methods

Methods are similar to subroutines, but different enough to merit their own keyword, method . The most obvious differences are that they're invoked on an object (or class), and they 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 :

 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. This is particularly handy since any method called without an explicit object defaults to $_ :

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

Method declarations support the same syntax as subroutines for optional, named, variadic, and typed parameters, default values for parameters, properties on parameters, and return values. Method calls support positional and named argument passing just like subroutines. (See Chapter 5 for more details on this syntax.)

You can call a method in one of two ways. The standard method call is connected to the object with the . operator:

 $ship.shut_down($infinity); 

An indirect object call is an alternative to the standard method call. This syntax looks like an ordinary subroutine call, except that the invocant is separated from the other arguments by a colon:

 shut_down($ship: $infinity); 

The parentheses are optional unless the method call is ambiguous without them:

 shut_down $ship: $infinity; 

6.2.3 Inheritance

Any class can inherit methods from another class using the is keyword in the class declaration. You may have noticed that 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.

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

Any class can inherit from multiple parent classes:

 class Heart::Gold is Ship is Improbable {     .... } 

Within a derived class, inherited attributes are accessible only 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";     } } 

6.2.4 Construction, Initialization, and Destruction

The default new method provided by the Object base class constructs and initializes opaque objects. It does this by calling bless , which calls the CREATE and BUILDALL methods. The CREATE method constructs an opaque object. The BUILDALL method calls the initializers for all inherited classes and finally the class's own initializer. BUILDALL actually calls the parent's BUILDALL method, which calls its parent's BUILDALL method, etc. The initializer for each class is BUILD . The default BUILD initializes the attributes of the object with named arguments to new , matching the name of the argument to the name of the attribute.

There are a number of ways to change the default object construction and initialization behavior. If you override new so that it passes a data structure as the first argument to bless , it will construct a traditional blessed hash (or array, or . . . ) object instead of calling CREATE to construct an opaque object:

 $class.bless({answer => '42'}); 

If you override the CREATE method you can alter the way objects are constructed . If you override the BUILDALL method you can change how the initializers for inherited classes are called. If you override the BUILD method you can change how the current class initializes objects and their attributes. Overriding BUILD will be common. Overriding CREATE and BUILDALL will be rare, since their default behavior is designed to handle everything from the simple opaque object to inheriting from classes written in other languages.

Object destruction traverses the inheritance hierarchy in the reverse order of object initialization. Objects are created from least derived to most derived and destroyed from most derived to least derived. The DESTROYALL method first calls the DESTROY method of the current class, and then calls the DESTROYALL method of the parent class (which calls its own DESTROY and then its own parent's DESTROYALL , etc). You will rarely need to define a DESTROY method, since the interpreter handles memory deallocation. It can be useful for class-specific cleanup, like closing a socket or filehandle.

6.2.5 Lexically Scoped Classes

Classes in Perl 6 are first class entities with entries in symbol tables or lexical scratchpads. [1] This means classes can be lexically scoped, just like variables or subroutines:

[1] If you're curious , : : is the sigil for classes and packages, though it's rarely needed in code.

 my class Infinite::Improbablity {      . . .  } $drive = Infinite::Improbability.new( ); 

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

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



Perl 6 and Parrot Essentials
Perl 6 and Parrot Essentials, Second Edition
ISBN: 059600737X
EAN: 2147483647
Year: 2003
Pages: 116

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net