Introduction to Object Oriented Perl

[ Perl tips index ]
[ Subscribe to Perl tips ]

Happy new year, and welcome to our first Perl tip for 2005. This week we'll briefly introduce the concepts of Object Oriented programming, and how it relates to Perl.

The basic concepts of object orientated design are simple. A programmer is able to create 'objects' that represent concepts in the appropriate problem domain. A program working with databases may have objects representing connections, queries, and rows of data. A human resources program might have objects representing staff, contractors, departments and budgets.

Objects usually group together a collection of related data, called attributes. However if that was the only defining feature of objects, then we could just as happily do our job with hashes or arrays instead. What makes objects special is that they belong to a 'class', and this class defines ways of manipulating and using the object, called 'methods'.

As an example, we all belong to the 'Human' class. Humans have a number of attributes including a name, height, weight, nationality, eye colour, age and gender. As members of the Human class, we possess all of these attributes. Likewise, Humans can walk, talk, watch television, and sleep. I can perform these actions because the class of Humans can perform these actions.

The creation of classes in Perl is done using the 'package' keyword, and this will be the topic of our next Perl Tips article. However, you don't need to know how classes are built in order to use them. Most useful classes have a 'constructor' method, typically called 'new' by convention, that allows you to create a new member of that class. We can call methods on classes and objects using Perl's arrow notation:

    # Create a new 'Human' object.  'Human->new' is the call to the
    # class constructor function.  In this case we're giving our
    # constructor two named arguments, one for the person's name,
    # and the other their eye colour.

    my $person = Human->new(name => "Paul", eye_colour => "green");

    # Now that we've created our person, which exists in a scalar,
    # we can call methods on that person.

    $person->watch_tv("Buffy");

Looking back to our human resources example, it would be natural to define a class of 'Staff' objects. Staff have a number of attributes that the business finds useful (name, address, annual leave accrued, salary, job title, and so on), but they also have a number of methods. Staff can be given a salary raise, they can work overtime, be transferred between departments and projects, and can take days of leave.

    my $bob = Staff->new( name => "Bob the Builder",
                          employee_num => 12345,
                          salary => 80000,
                          position => "Engineer and Entertainer",
    );

    # Pay Bob his fortnightly wage.
    $bob->pay_wage;

    # Transfer Bob to a new project.
    $bob->assigned_project("Build Toy Factory");

One of the big advantages of Object Oriented design is that existing classes can be extended into more specialised classes. In this case we say that the new class 'inherits' the properties of the older class. This is one of the greatest advantages of Object Oriented design. It works equally well for both classes developed in-house, and also for modules available from CPAN. Inheriting from third-party classes is an excellent way to handle the case where your changes are not appropriate for submitting back to the module source.

Our organisation may have casual staff, who instead of being paid a fixed wage, instead need to submit a timesheet and are paid based upon the number of hours worked each day at an hourly rate. Rather than having to define an entirely new class, we can just extend our existing one.

    # Staff::Casual inherits from our Staff class.
    # We'll see how to inherit from classes in a later
    # Perl Tip.  Inheritance is discussed in depth in
    # Damian Conway's "Advanced Object Oriented Perl" course.

    my $dizzy = Staff::Casual->new( name => "Dizzy",
                                    employee_number => 12346,
                                    hourly_wage => 20,
                                    position => "Cement Mixer");

    $dizzy->log_time(date => "2005-01-10", hours => 6);

Now when we want to pay our staff, we can treat all the staff objects in the same way. Permanent staff will be paid a fixed wage and casual staff will be paid according to their timesheet:

    foreach my $employee ($bob, $dizzy) {
        $employee->pay_wage;
    }

This behaviour of different classes of objects responding differently to the same method call is known as 'polymorphism'.

Since Perl is dynamically typed, it always calls the method associated with the most derived (or child) class when making polymorphic calls, which is almost always what we want. Some statically typed languages would call the methods on the base class, possibly resulting in our casual staff members being paid a fixed wage without needing to attend work.

Next week we'll cover how to create both classes and objects in Perl.

[ Perl tips index ]
[ Subscribe to Perl tips ]


This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.

If you have any questions please don't hesitate to contact us:

Email: contact@perltraining.com.au
Phone: 03 9354 6001 (Australia)
International: +61 3 9354 6001

Valid XHTML 1.0 Valid CSS