Friday, June 8, 2007

In [our] journey since the lasttwo posts, we've covered a bit of introductory Perl 6 ranging from a scalar to currying functions and other tom foolery. Here, we'll discuss a big part of Perl 6: Object oriented programming.

Anybody who comes from a Perl 5 background probably knew that Object-orientation wasn't exactly first class; I don't even know if you'd define it as 'coach.' Perl 6 now extends this to full object-orientation. -Real- object-orientation, if you wish to think of it in that manner.That means this will most likely be long ride. So, we should probably get on soon as possible.

ClassesClass declaration comes in two forms:

class Foo; #rest of file is class definition

class Bar { ... }; #block is class definition

The first can only be used as the first declaration [statement] in the file or string (in the case of eval.)

AttributesAttributes are known in other cultures as instance variables of a class. They are declared with the has keyword, and declared public with a "." sigil following the primary sigil (see below); this generates accessor methods in the class of the same name. Private attributes that indicate no accessor method are declared with the secondary "!" sigil. Ex:

MethodsMethods are a lot like subroutines, but with their own keyword method. The obvious difference is they're invoked on objects. In Perl 6, many of the primitive types are objects like Int and String. That is how we invoked methods such as .say(); Ex:

The last way is an indirect object call. It acts like a subroutine, with the object seperated from the parameters. The parameters are comma seperated after the colon, i.e.: doit($object: 1,"world");And of course, the parenthesis are optional.InheritanceClasses can inherit from one another using the is keyword. That is, the act of saying a class inherits from another is just a class trait. Ex:

RolesA role is a reusable unit of class code. In the way that modules export subroutines and the like for other modules and your code, a role exports methods and attributes into a class. This is like inheritence; inheritence is just a different way to reuse code.

When you use roles with a class, they are treated almost as if you had simply typed in that code right there. With inheritence you only have accessor methods to access your attributes; with role's they can be referenced by their $.name (this applies to private attributes as well.) Ex:

Using Roles, it is as if we wrote the code in Hi directly in the declaration of class Foobar. This is reusable, and it can be used to give methods to classes that need similar functionality, but without an inheritence relationship.

An interface is a role that only defines method stubs, and no attributes.

Role ConflictsGiven one class defined over two roles, each with a method of the same name, which method should the class take when it's invoked? Either. In Perl 6, you simply choose one, and you can do it by giving a full name of the method you want to call (the format is Role::method) given the roles your class uses.

DelegationDelegation lets you act like another object's methods are your own methods. You use the handles keyword to specify what methods will act on what attributes rather than on the object itself. It sounds confusing, but it's easy in practice and gives you some nice reusable code. Ex:

We can do this thanks to the joys of multiple inheritance via multiple is traits.

Multiple dispatches and Operator overloadingIn the last article we discussed multi subroutines that applied to having two subroutines of the same name, with different signatures. multi applies to any code object like a sub, method or submethod. Ex:

Operator overloading make use of multiple dispatch. Operators are just subs with a special syntax that describes how they are used in an expression. You can define an operator as prefix, postfix (unary), or infix (binary.)

Operators are defined with subs in the form of multi sub how:exp.how is that of the above (prefix postfix and infix), while exp defines the operator to overload, using any method to treat it as a hash subscript, i.e. you could use <+>, <<+>>, {'+'}, etc..Ex:

The * at the start of the multi-sub definition indicates that it is in global scope; without this, the operation of addition is lexically scoped to the area at which it was defined. Generally, you'll probably want to use *, though. As of pugs r16643, operator overloading in this fashion does not seem to work yet.

ConclusionThis time we looked at a very big part of Perl 6. Just by using simple features like Roles and Delegations in Perl 6, you can achieve some very powerful constructs. You also get all the classic object-oriented features you'd expect from other languages.Have fun. :)