Copyright Notice

This text is copyright by InfoStrada Communications, Inc., and is used with their permission. Further distribution or use is not permitted.

This text has appeared in an edited form in Linux Magazine 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.

Please read all the information in the table of contents before using this article.

Linux Magazine Column 12 (May 2000)

[suggested title: Introductions to Objects, part 2]

Last month, I started talking about Perl objects, introducing the method arrow syntax, as follows:

  Class->method(@args);

or the equivalent:

  $a = "Class";
  $a->method(@args);

which constructs an argument list of:

  ("Class", @args)

and attempts to invoke

  Class::method("Class", @args);

However, if Class::method is not found, then @Class::ISA is examined (recursively) to locate a package that does indeed contain method, and that subroutine is invoked instead.

Using this simple syntax, we have class methods, (multiple) inheritance, overriding, and extending. Using just what we've seen so far, we've been able to factor out common code, and provide a nice way to reuse implementations with variations. This is at the core of what objects provide, but objects also provide instance data, which we haven't even begun to cover. Until now.

A horse is a horse, of course of course -- or is it?

Let's start with the code from last month for the Animal class and the Horse class:

  { package Animal;
    sub speak {
      my $class = shift;
      print "a $class goes ", $class->sound, "!\n"
    }
  }
  { package Horse;
    @ISA = qw(Animal);
    sub sound { "neigh" }
  }

This lets us invoke Horse->speak to ripple upward to Animal::speak, calling back to Horse::sound to get the specific sound, and the output of:

  a Horse goes neigh!

But all of our Horse objects would have to be absolutely identical. If I add a subroutine, all horses automatically share it. That's great for making horses the same, but how do we capture the distinctions about an individual horse? For example, suppose I want to give my first horse a name. There's got to be a way to keep its name separate from the other horses.

We can do that by drawing a new distinction, called an ``instance''. An ``instance'' is generally created by a class. In Perl, any reference can be an instance, so let's start with the simplest reference that can hold a horse's name: a scalar reference.

  my $name = "Mr. Ed";
  my $talking = \$name;

So now $talking is a reference to what will be the instance-specific data (the name). The final step in turning this into a real instance is with a special operator called bless:

  bless $talking, Horse;

This operator stores information about the package named Horse into the thing pointed at by the reference. At this point, we say $talking is an instance of Horse. That is, it's a specific horse. The reference is otherwise unchanged, and can still be used with traditional dereferencing operators.

Invoking an instance method

The method arrow can be used on instances, as well as names of packages (classes). So, let's get the sound that $talking makes:

  my $noise = $talking->sound;

To invoke sound, Perl first notes that $talking is a blessed reference (and thus an instance). It then constructs an argument list, in this case from just ($talking). (Later we'll see that arguments will take their place following the instance variable, just like with classes.)

Now for the fun part: Perl takes the class in which the instance was blessed, in this case Horse, and uses that to locate the subroutine to invoke the method. In this case, Horse::sound is found directly (without using inheritance), yielding the final subroutine invocation:

  Horse::sound($talking)

Note that the first parameter here is still the instance, not the name of the class as before. We'll get neigh as the return value, and that'll end up as the $noise variable above.

If Horse::sound had not been found, we'd be wandering up the @Horse::ISA list to try to find the method in one of the superclasses, just as for a class method. The only difference between a class method and an instance method is whether the first parameter is a instance (a blessed reference) or a class name (a string).

Accessing the instance data

Because we get the instance as the first parameter, we can now access the instance-specific data. In this case, let's add a way to get at the name:

  { package Horse;
    @ISA = qw(Animal);
    sub sound { "neigh" }
    sub name {
      my $self = shift;
      $$self;
    }
  }
    
Now we call for the name:
  print $talking->name, " says ", $talking->sound, "\n";

Inside Horse::name, the @_ array contains just $talking, which the shift stores into $self. (It's traditional to shift the first parameter off into a variable named $self for instance methods, so stay with that unless you have strong reasons otherwise.) Then, $self gets de-referenced as a scalar ref, yielding Mr. Ed, and we're done with that. The result is:

  Mr. Ed says neigh.

How to build a horse

Of course, if we constructed all of our horses by hand, we'd most likely make mistakes from time to time. We're also violating one of the properties of object-oriented programming, in that the ``inside guts'' of a Horse are visible. That's good if you're a veterinarian, but not if you just like to own horses. So, let's let the Horse class build a new horse:

  { package Horse;
    @ISA = qw(Animal);
    sub sound { "neigh" }
    sub name {
      my $self = shift;
      $$self;
    }
    sub named {
      my $class = shift;
      my $name = shift;
      bless \$name, $class;
    }
  }

Now with the new named method, we can build a horse:

  my $talking = Horse->named("Mr. Ed");

Notice we're back to a class method, so the two arguments to Horse::named are Horse and Mr. Ed. The bless operator not only blesses $name, it also returns the reference to $name, so that's fine as a return value. And that's how to build a horse.

Inheriting the constructor

But was there anything specific to Horse in that method? No. Therefore, it's also the same recipe for building anything else that inherited from Animal, so let's put it there:

  { package Animal;
    sub speak {
      my $class = shift;
      print "a $class goes ", $class->sound, "!\n"
    }
    sub name {
      my $self = shift;
      $$self;
    }
    sub named {
      my $class = shift;
      my $name = shift;
      bless \$name, $class;
    }
  }
  { package Horse;
    @ISA = qw(Animal);
    sub sound { "neigh" }
  }

Ahh, but what happens if we invoke speak on an instance?

  my $talking = Horse->named("Mr. Ed");
  $talking->speak;

We get a debugging value:

  a Horse=SCALAR(0xaca42ac) goes neigh!

Why? Because the Animal::speak routine is expecting a classname as its first parameter, not an instance. When the instance is passed in, we'll end up using a blessed scalar reference as a string, and that shows up as we saw it just now.

Making a method work with either classes or instances

All we need is for a method to detect if it is being called on a class or called on an instance. The most straightforward way is with the ref operator. This returns a string (the classname) when used on a blessed reference, and undef when used on a string (like a classname). Let's modify the name method first to notice the change:

  sub name {
    my $either = shift;
    ref $either
      ? $$either # it's an instance, return name
      : "an unnamed $either"; # it's a class, return generic
  }

Here, the ?: operator comes in handy to select either the dereference or a derived string. Now we can use this with either an instance or a class. Note that I've changed the first parameter holder to $either to show that this is intended:

  my $talking = Horse->named("Mr. Ed");
  print Horse->name, "\n"; # prints "an unnamed Horse\n"
  print $talking->name, "\n"; # prints "Mr Ed.\n"

and now we'll fix speak to use this:

  sub speak {
    my $either = shift;
    print $either->name, " goes ", $either->sound, "\n";
  }

And since sound already worked with either a class or an instance, we're done!

Adding parameters to a method

Let's train our animals to eat:

  { package Animal;
    sub named {
      my $class = shift;
      my $name = shift;
      bless \$name, $class;
    }
    sub name {
      my $either = shift;
      ref $either
        ? $$either # it's an instance, return name
        : "an unnamed $either"; # it's a class, return generic
    }
    sub speak {
      my $either = shift;
      print $either->name, " goes ", $either->sound, "\n";
    }
    sub eat {
      my $either = shift;
      my $food = shift;
      print $either->name, " eats $food.\n";
    }
  }
  { package Horse;
    @ISA = qw(Animal);
    sub sound { "neigh" }
  }
  { package Sheep;
    @ISA = qw(Animal);
    sub sound { "baaaah" }
  }

And now try it out:

  my $talking = Horse->named("Mr. Ed");
  $talking->eat("hay");
  Sheep->eat("grass");

which prints:

  Mr. Ed eats hay.
  an unnamed Sheep eats grass.

An instance method with parameters gets invoked with the instance, and then the list of parameters. So that first invocation is like:

  Animal::eat($talking, "hay");

More interesting instances

What if an instance needs more data? Most interesting instances are made of many items, each of which can in turn be a reference or even another object. The easiest way to store these is often in a hash. The keys of the hash serve as the names of parts of the object (often called ``instance variables'' or ``member variables''), and the corresponding values are, well, the values.

But how do we turn the horse into a hash? Recall that an object was any blessed reference. We can just as easily make it a blessed hash reference as a blessed scalar reference, as long as everything that looks at the reference is changed accordingly.

Let's make a sheep that has a name and a color:

  my $bad = bless { Name => "Evil", Color => "black" }, Sheep;

so $bad->{Name} has Evil, and $bad->{Color} has black. But we want to make $bad->name access the name, and that's now messed up because it's expecting a scalar reference. Not to worry, because that's pretty easy to fix up:

  ## in Animal
  sub name {
    my $either = shift;
    ref $either ?
      $either->{Name} :
      "an unnamed $either";
  }

And of course named still builds a scalar sheep, so let's fix that as well:

  ## in Animal
  sub named {
    my $class = shift;
    my $name = shift;
    my $self = { Name => $name, Color => $class->default_color };
    bless $self, $class;
  }

What's this default_color? Well, if named has only the name, we still need to set a color, so we'll have a class-specific initial color. For a sheep, we might define it as white:

  ## in Sheep
  sub default_color { "white" }

And then to keep from having to define one for each additional class, we'll define a ``backstop'' method that serves as the ``default default'', directly in Animal:

  ## in Animal
  sub default_color { "brown" }

Now, because name and named were the only methods that referenced the ``structure'' of the object, the rest of the methods can remain the same, so speak still works as before.

A horse of a different color

But having all our horses be brown would be boring. So let's add a method or two to get and set the color.

  ## in Animal
  sub color {
    $_[0]->{Color}
  }
  sub set_color {
    $_[0]->{Color} = $_[1];
  }

Note the alternate way of accessing the arguments: $_[0] is used in-place, rather than with a shift. (This saves us a bit of time for something that may be invoked frequently.) And now we can fix that color for Mr. Ed:

  my $talking = Horse->named("Mr. Ed");
  $talking->set_color("black-and-white");
  print $talking->name, " is colored ", $talking->color, "\n";

which results in:

  Mr. Ed is colored black-and-white

Summary

So, now we have class methods, constructors, instance methods, instance data, and even accessors. But that's still just the beginning of what Perl has to offer. We haven't even begun to talk about accessors that double as getters and setters, destructors, indirect object notation, subclasses that add instance data, per-class data, overloading, ``isa'' and ``can'' tests, UNIVERSAL class, and so on. Perhaps in a future column, eh?

For more information, see the Perl documentation for perlobj (the reference information about objects), perltoot (the tutorial for those who already knw objects), perlbot (for some more tricks), and books such as Damian Conway's excellent Object Oriented Perl. And as always, enjoy!


Randal L. Schwartz is a renowned expert on the Perl programming language (the lifeblood of the Internet), having contributed to a dozen top-selling books on the subject, and over 200 magazine articles. Schwartz runs a Perl training and consulting company (Stonehenge Consulting Services, Inc of Portland, Oregon), and is a highly sought-after speaker for his masterful stage combination of technical skill, comedic timing, and crowd rapport. And he's a pretty good Karaoke singer, winning contests regularly.

Schwartz can be reached for comment at merlyn@stonehenge.com or +1 503 777-0095, and welcomes questions on Perl and other related topics.