All objects are references, but not all references are objects. A reference won't work as an object unless its referent is specially marked to tell Perl what package it belongs to. The act of marking a referent with a package name--and therefore, its class, since a class is just a package--is known as blessing. You can think of the blessing as turning a reference into an object, although it's more accurate to say that it turns the reference into an object reference.
The bless
function takes either one
or two arguments. The first argument is a reference and the second is
the package to bless the referent into. If the second argument is
omitted, the current package is used.
$obj = { }; # Get reference to anonymous hash. bless($obj); # Bless hash into current package. bless($obj, "Critter"); # Bless hash into class Critter.
Here we've used a reference to an anonymous hash, which is what people usually use as the data structure for their objects. Hashes are extremely flexible, after all. But allow us to emphasize that you can bless a reference to anything you can make a reference to in Perl, including scalars, arrays, subroutines, and typeglobs. You can even bless a reference to a package's symbol table hash if you can think of a good reason to. (Or even if you can't.) Object orientation in Perl is completely orthogonal to data structure.
Once the referent has been blessed, calling the
built-in ref
function on its reference returns the
name of the blessed class instead of the built-in type, such as
HASH
. If you want the built-in type, use the
reftype
function from the
attributes
module. See use
attributes
in Glossary.
And that's how to make an object. Just take a reference
to something, give it a class by blessing it into a package, and
you're done. That's all there is to it if you're designing a minimal
class. If you're using a class, there's even less to it, because the
author of a class will have hidden the bless
inside
a method called a constructor, which creates and
returns instances of the class. Because bless
returns its first argument, a typical constructor can be as simple as
this:
package Critter; sub spawn { bless {}; }
Or, spelled out slightly more explicitly:
package Critter; sub spawn { my $self = {}; # Reference to an empty anonymous hash bless $self, "Critter"; # Make that hash a Critter object return $self; # Return the freshly generated Critter }
With that definition in hand, here's how one might create a
Critter
object:
$pet = Critter->spawn;
Like all methods, a constructor is just a subroutine, but we don't call it as a subroutine. We always invoke it as a method--a class method, in this particular case, because the invocant is a package name. Method invocations differ from regular subroutine calls in two ways. First, they get the extra argument we discussed earlier. Second, they obey inheritance, allowing one class to use another's methods.
We'll describe the underlying mechanics of inheritance more
rigorously in the next section, but for now, some simple examples of
its effects should help you design your constructors. For instance,
suppose we have a Spider
class that inherits
methods from the Critter
class. In particular,
suppose the Spider
class doesn't have its own
spawn
method. The following correspondences
apply:
Method Call | Resulting Subroutine Call |
---|---|
Critter->spawn() | Critter::spawn("Critter") |
Spider->spawn() | Critter::spawn("Spider") |
The subroutine called is the same in both cases, but the
argument differs. Note that our spawn
constructor
above completely ignored its argument, which means our
Spider
object was incorrectly blessed into class
Critter
. A better constructor would provide the
package name (passed in as the first argument) to
bless
:
sub spawn { my $class = shift; # Store the package name my $self = { }; bless($self, $class); # Bless the reference into that package return $self; }
Now you could use the same subroutine for both these cases:
$vermin = Critter->spawn; $shelob = Spider->spawn;
And each object would be of the proper class. This even works indirectly, as in:
$type = "Spider"; $shelob = $type->spawn; # same as "Spider"->spawn
That's still a class method, not an instance method, because its invocant holds a string and not a reference.
If $type
were an object instead of
a class name, the previous constructor definition wouldn't have
worked, because bless
needs a class name. But for
many classes, it makes sense to use an existing object as the
template from which to create another. In these cases, you can
design your constructors so that they work with either objects or
class names:
sub spawn { my $invocant = shift; my $class = ref($invocant) || $invocant; # Object or class name my $self = { }; bless($self, $class); return $self; }
Most objects maintain internal information that is indirectly manipulated by the object's methods. All our constructors so far have created empty hashes, but there's no reason to leave them empty. For instance, we could have the constructor accept extra arguments to store into the hash as key/value pairs. The OO literature often refers to such data as properties, attributes, accessors, member data, instance data, or instance variables. The section "Instance Variables" later in this chapter discusses attributes in more detail.
Imagine a Horse
class with instance
attributes like "name" and "color":
$steed = Horse->new(name => "Shadowfax", color => "white");
If the object is implemented as a hash reference, the key/value pairs can be interpolated directly into the hash once the invocant is removed from the argument list:
sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = { @_ }; # Remaining args become attributes bless($self, $class); # Bestow objecthood return $self; }
This time we used a method named
new
for the class's constructor, which just might
lull C++ programmers into thinking they know what's going on. But
Perl doesn't consider "new
" to be anything
special; you may name your constructors whatever you like. Any
method that happens to create and return an object is a de facto
constructor. In general, we recommend that you name your
constructors whatever makes sense in the context of the problem
you're solving. For example, constructors in the
Tk
module are named after the widgets they
create. In the DBI
module, a constructor named
connect
returns a database handle object, and
another constructor named prepare
is invoked as
an instance method and returns a statement handle object. But if
there is no suitable context-specific constructor name,
new
is perhaps not a terrible choice. Then again,
maybe it's not such a bad thing to pick a random name to force
people to read the interface contract (meaning the class
documentation) before they use its constructors.
Elaborating further, you can set up your constructor with default key/value pairs, which the user could later override by supplying them as arguments:
sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = { color => "bay", legs => 4, owner => undef, @_, # Override previous attributes }; return bless $self, $class; } $ed = Horse->new; # A 4-legged bay horse $stallion = Horse->new(color => "black"); # A 4-legged black horse
This Horse
constructor ignores its
invocant's existing attributes when used as an instance method. You
could create a second constructor designed to be called as an
instance method, and if designed properly, you could use the values
from the invoking object as defaults for the new one:
$steed = Horse->new(color => "dun"); $foal = $steed->clone(owner => "EquuGen Guild, Ltd."); sub clone { my $model = shift; my $self = $model->new(%$model, @_); return $self; # Previously blessed by ->new }
(You could also have rolled this functionality directly into
new
, but then the name wouldn't quite fit the
function.)
Notice how even in the clone
constructor,
we don't hardcode the name of the Horse
class. We
have the original object invoke its own new
method, whatever that may be. If we had written that as
Horse->new
instead of
$model->new
, then the class wouldn't have
facilitated inheritance by a Zebra
or
Unicorn
class. You wouldn't want to clone Pegasus
and suddenly find yourself with a horse of a different color.
Sometimes, however, you have the opposite problem:
rather than trying to share one constructor among several classes,
you're trying to have several constructors share one class's object.
This happens whenever a constructor wants to call a base class's
constructor to do part of the construction work. Perl doesn't do
hierarchical construction for you. That is, Perl does not
automatically call the constructors (or the destructors) for any
base classes of the class requested, so your constructor will have
to do that itself and then add any additional attributes the derived
class needs. So the situation is not unlike the
clone
routine, except that instead of copying an
existing object into the new object, you want to call your base
class's constructor and then transmogrify the new base object into
your new derived object.