Categories

Posts in this category

Sun, 23 Aug 2009

Let's build an object


Permanent link

Building an object in Perl 6 is rather easy. As the author of a class you don't really have to care (at least in the simplest case), you inherit a default constructor from class Object. As a consumer of that class you just write YourClass.new(attrib1 => $value1) to create an object of class YourClass, at the same time initializing an attribute.

Running initializations code

If you want to run some initialization code on object creation, you don't have to touch the new method at all. Something like this works:

class C {
    submethod BUILD {
        say "Created a new instance of C";
    }
}

C.new();

The BUILD submethod is called by the constructor automatically, and can do any initialization that's necessary. It also receives the named arguments that the user passes on to new().

(In case you wonder, a submethod is a public method that's not inherited to child classes).

Custom constructors

Suppose you're not a big fan of named arguments, and you want to write a constructor that takes one mandatory positional parameter. In that case you'd write a custom new method. To create an object, that method has to call self.bless:

class C {
    has $.size;
    method new($x) {
        self.bless(*, size => 2 * $x);
    }
}

say C.new(3).size;      # prints 6

The star * as the first argument to bless tells it to create an empty object itself.

If you want to enable additional named parameters, that's easily done:

class C {
    has $.size;
    method new($x, %n) {
        self.bless(*, size => 2 * $x, |%n);
    }
}

Note that these two concepts (custom new() and BUILD() (sub)methods) are orthogonal; you can use both at once, and both peacefully coexist.

Understanding object initialization

As demonstrated above you don't need to understand the full process of building and initializing objects to manipulate it. If you still want to know, read on.

Suppose you have a class C which inherits from another class B, then the process of building an object of class C looks like this:

Perl 6 object creation

The user calls C.new (which is inherited from class Object), which in turn calls self.bless(*, |%args). bless creates a new P6Opaque object which is the storage for the newly created object. This is the call to CREATE in the image above.

After the storage has been allocated and the attributes initialized, new passes control to BUILDALL (passing along all named parameters), which in turn calls BUILD in all classes in the inheritance hierarchy, starting at the top of the hierarchy and calling the BUILD method of class C at last.

This design allows you to substitute parts of the initialization with least effort, and especially writing custom new and BUILD methods very easily.

Instead of passing a * to bless, you can also pass along an object of different storage type, which means that you can instruct Perl 6 to store your objects by a different mechanism, for example by the gnome library GObject or similar (though that's not yet implemented in Rakudo).

[/perl-6] Permanent link

Comments / Trackbacks:

Trackback URL: /blog-en/perl-6/object-construction-and-initialization.trackback

Chris Dolan wrote

Thanks!
This is exactly the explanation I've been seeking for over a year. Thank you!

Write a comment

The comments on this blog post have been disabled; the comment form below will not work.

 
Name:
URL: [http://www.example.com/] (optional)
Title: (optional)
Comments:
Save my Name and URL/Email for next time