Copyright Notice

This text is copyright by CMP Media, LLC, and is used with
their permission. Further distribution or use is not permitted.

This text has appeared in an edited form in
SysAdmin/PerformanceComputing/UnixReview magazine.
However, the version you are reading here is as the author
originally submitted the article for publication, not after their
editors applied their creativity.

Objects, objects, objects! The programming world seems to be going
``object-oriented''. And Perl is no exception -- it too, has objects
for the most recent 30% of its public life. However, unlike some
other popular programming languages, you can write Perl code using
objects, or avoid them entirely. Let's take a look at Perl's object
system.

A Perl ``object'' is nothing more than a reference to a data structure.
(I've used references in a number of the previous columns, if you need
a refresher, or see ``man perlref'' on your system.) However, the
reference has been ``blessed'' into a particular package, making this
package the ``class'' of the object.

The purpose of the blessing is to allow ``methods'' to be called later
on this object. A method is nothing more than an ordinary subroutine,
but the subroutine is found within the package from which the object
was blessed.

Let's take a look at a simple example. I'm going to create an object
class called Car. Within it, I'm going to put a method that creates
new cars for me to use, called ``new''. The invocation looks like this:

$myCar = new Car;

Now, in order for this to work, we'll need to have a subroutine
called ``new'' in the package Car. It'll look like this:

The subroutine is in the Car package, named ``new''. There's nothing
special about the name ``new'', but it makes C++ and Smalltalk users
feel like they know what's going on.

The first parameter passed into this subroutine is the class name
(that is, the package name). This subroutine shifts the parameter off
into a local variable called $class. This is one of the things that
distinguishes a method invocation from an ordinary subroutine
invocation: there's always an extra first parameter.

The ``object'' is created using a local variable $self. This variable
is initialized to an empty anonymous hash. This is a fairly common
practice, because instance variables (variables that are unique to
each object) are then just elements of this hash.

The object is ``blessed'' into this package. This doesn't change the
value of $self, but the anonymous hash will now ``remember'' that it
came from this package. This ``memory'' allows methods to be found in
the right package later.

An instance variable called ``passengers'' is created as an empty
anonymous hash (reference) inside $self.

Finally, the value of $self is returned.

Note that the return value is thus a reference to an anonymous hash,
but this hash has been blessed into the Car package. You could thus
use the variable $myCar (defined earlier) just like any hashref.
However, objects work best when we treat them as ``black boxes'',
instead interfacing with the object through ``instance methods''.

Let's look at an instance method on this car. Let's put ``Fred''
and ``Wilma'' into the car:

enter $myCar qw(Fred Wilma);

The difference here is that instead of a classname after the method
name, we now have an instance name. Also notice that we have a
parameter passed to the method following the instance name. Let's
see what that looks like inside the subroutine's definition:

Once again, a number of things are happening here. Let's walk through
this one:

Like the class method invocation of ``new'', there's an extra first
parameter here. In this case, it's the instance (like $myCar). The
first step of this subroutine shifts that instance off into a variable
called $self. This will be the same $self as was defined in the ``new''
subroutine.

Once the value for $self has been shifted off, the remaining values of
@_ are now the people that we wish to put into the car. The foreach
loop sets elements within the ``passengers'' instance variable (which is
in turn referenced as an element in the hash for $self). The key will
be the name of the passenger, and the corresponding value is just
``seat'', showing that they have a seat (a later version of this
subroutine will perhaps record the choice of seats, but let's keep it
simple for now).

Although the return value of this method is really the side effect of
having changed $self, we return $self once again, for reasons that
will become obvious below.

So, this method causes the ``passengers'' instance variable to include
the people listed as arguments to the subroutine.

Sometimes, the invocation syntax is better written using arrow
notation, which looks like this:

$myCar = Car->new;
$myCar->enter(qw(Fred Barney));

In fact, because the return value of the enter method is the object again,
we can combine this:

$myCar = Car->new->enter(qw(Fred Barney));

This is the advantage of the arrow notation. We can also write this
using the other (``indirect object'') notation as:

$myCar = enter {new Car} qw(Fred Barney);

but as you can see, the parameters start to move further and further
from the method name.

Once the passengers have been added, we'll need to see who they are.
That's handled with an additional instance method:

Note here the value of $myCar when interpreted as a string. It's
really just a debugging number, in the form of:

Class=UNDERLYINGTYPE(0xHexAddress)

Also note that the user of the Car class does not need to know that we
have stored the passengers as a hash... if we find it more efficient
later to change that to a B-tree or a sorted list, we can do so, as
long as the interfaces remain the same. That's why it's important to
treat the object as a black box.

Once again, the first parameter is the object itself (like $myCar).
This value is then accessed for the hash at the instance variable
``passengers''. The keys() operator is called on this hash, and the
result is sorted ASCIIbetically.

Let's add one more method for completeness -- a way to remove the
passengers that have been added. That'd look like this:

Here, we set up two family cars in a hash called %cars. The key of
the hash is the family name, and the corresponding value will be a
particular car (of class Car). Then, there's a little routine that
dumps out the current occupants of the car.

This then lets us perform typical transactions, such as Wilma jumping
out from one car and into another:

## wilma decides it is better to ride with betty
$cars{Flintstone}->leave("Wilma");
$cars{Rubble}->enter("Wilma");

Hmm. Let's wrap this typical operation up into a method, and illustrate
named parameters at the same time.

## wilma goes to the rubble car
$cars{Flintstone}->jump(
PEOPLE => qw(Wilma),
TO => $cars{Rubble},
);
## but it breaks down, so they all go to the other car
$cars{Rubble}->jump(
TO => $cars{Flintstone},
);
## and then that breaks down, so they all get in a new car
$newCar = $cars{Flintstone}->jump;
@passengers = $newCar->passengers;
print "new car contains @passengers\n";

Try these examples out. There's a lot to experment with here.

As you can see, objects allow us to define a new data type (a car) and
operations on that type. In a future column, I'll illustrate other
object things, like inheritance. Enjoy!