SEARCH
NEW RPMS
DIRECTORIES
ABOUT
FAQ
VARIOUS
BLOG

BotDetect - Real-Time Bot Detection API
 
 

MAN page from Old RedHat 5.X perl-5.004-4.i386.rpm

PERLTOOT

Section: Perl Programmers Reference Guide (1)
Updated: perl 5.004, patch 04
Index 

NAME

perltoot - Tom's object-oriented tutorial for perl 

DESCRIPTION

Object-oriented programming is a big seller these days. Some managerswould rather have objects than sliced bread. Why is that? What's sospecial about an object? Just what is an object anyway?

An object is nothing but a way of tucking away complex behaviours intoa neat little easy-to-use bundle. (This is what professors callabstraction.) Smart people who have nothing to do but sit around forweeks on end figuring out really hard problems make these niftyobjects that even regular people can use. (This is what professors callsoftware reuse.) Users (well, programmers) can play with this littlebundle all they want, but they aren't to open it up and mess with theinsides. Just like an expensive piece of hardware, the contract saysthat you void the warranty if you muck with the cover. So don't do that.

The heart of objects is the class, a protected little private namespacefull of data and functions. A class is a set of related routines thataddresses some problem area. You can think of it as a user-defined type.The Perl package mechanism, also used for more traditional modules,is used for class modules as well. Objects ``live'' in a class, meaningthat they belong to some package.

More often than not, the class provides the user with little bundles.These bundles are objects. They know whose class they belong to,and how to behave. Users ask the class to do something, like ``giveme an object.'' Or they can ask one of these objects to do something.Asking a class to do something for you is calling a class method.Asking an object to do something for you is calling an object method.Asking either a class (usually) or an object (sometimes) to give youback an object is calling a constructor, which is just akind of method.

That's all well and good, but how is an object different from any otherPerl data type? Just what is an object really; that is, what's itsfundamental type? The answer to the first question is easy. An objectis different from any other data type in Perl in one and only one way:you may dereference it using not merely string or numeric subscriptsas with simple arrays and hashes, but with named subroutine calls.In a word, with methods.

The answer to the second question is that it's a reference, and not justany reference, mind you, but one whose referent has been bless()edinto a particular class (read: package). What kind of reference? Well,the answer to that one is a bit less concrete. That's because in Perlthe designer of the class can employ any sort of reference they'd likeas the underlying intrinsic data type. It could be a scalar, an array,or a hash reference. It could even be a code reference. But becauseof its inherent flexibility, an object is usually a hash reference. 

Creating a Class

Before you create a class, you need to decide what to name it. That'sbecause the class (package) name governs the name of the file used tohouse it, just as with regular modules. Then, that class (package)should provide one or more ways to generate objects. Finally, it shouldprovide mechanisms to allow users of its objects to indirectly manipulatethese objects from a distance.

For example, let's make a simple Person class module. It gets stored inthe file Person.pm. If it were called a Happy::Person class, it wouldbe stored in the file Happy/Person.pm, and its package would becomeHappy::Person instead of just Person. (On a personal computer notrunning Unix or Plan 9, but something like MacOS or VMS, the directoryseparator may be different, but the principle is the same.) Do not assumeany formal relationship between modules based on their directory names.This is merely a grouping convenience, and has no effect on inheritance,variable accessibility, or anything else.

For this module we aren't going to use Exporter, because we'rea well-behaved class module that doesn't export anything at all.In order to manufacture objects, a class needs to have a constructormethod. A constructor gives you back not just a regular data type,but a brand-new object in that class. This magic is taken care of bythe bless() function, whose sole purpose is to enable its referent tobe used as an object. Remember: being an object really means nothingmore than that methods may now be called against it.

While a constructor may be named anything you'd like, most Perlprogrammers seem to like to call theirs new(). However, new() is nota reserved word, and a class is under no obligation to supply such.Some programmers have also been known to use a function withthe same name as the class as the constructor. 

Object Representation

By far the most common mechanism used in Perl to represent a Pascalrecord, a C struct, or a C++ class is an anonymous hash. That's because ahash has an arbitrary number of data fields, each conveniently accessed byan arbitrary name of your own devising.

If you were just doing a simplestruct-like emulation, you would likely go about it something like this:

    $rec = {        name  => "Jason",        age   => 23,        peers => [ "Norbert", "Rhys", "Phineas"],    };
If you felt like it, you could add a bit of visual distinctionby up-casing the hash keys:

    $rec = {        NAME  => "Jason",        AGE   => 23,        PEERS => [ "Norbert", "Rhys", "Phineas"],    };
And so you could get at $rec->{NAME} to find ``Jason'', or@{ $rec->{PEERS} } to get at ``Norbert'', ``Rhys'', and ``Phineas''.(Have you ever noticed how many 23-year-old programmers seem tobe named ``Jason'' these days? :-)

This same model is often used for classes, although it is not consideredthe pinnacle of programming propriety for folks from outside theclass to come waltzing into an object, brazenly accessing its datamembers directly. Generally speaking, an object should be consideredan opaque cookie that you use object methods to access. Visually,methods look like you're dereffing a reference using a function nameinstead of brackets or braces. 

Class Interface

Some languages provide a formal syntactic interface to a class's methods,but Perl does not. It relies on you to read the documentation of eachclass. If you try to call an undefined method on an object, Perl won'tcomplain, but the program will trigger an exception while it's running.Likewise, if you call a method expecting a prime number as its argumentwith a non-prime one instead, you can't expect the compiler to catch this.(Well, you can expect it all you like, but it's not going to happen.)

Let's suppose you have a well-educated user of your Person class,someone who has read the docs that explain the prescribedinterface. Here's how they might use the Person class:

    use Person;
    $him = Person->new();    $him->name("Jason");    $him->age(23);    $him->peers( "Norbert", "Rhys", "Phineas" );
    push @All_Recs, $him;  # save object in array for later
    printf "%s is %d years old.\n", $him->name, $him->age;    print "His peers are: ", join(", ", $him->peers), "\n";
    printf "Last rec's name is %s\n", $All_Recs[-1]->name;
As you can see, the user of the class doesn't know (or at least, has nobusiness paying attention to the fact) that the object has one particularimplementation or another. The interface to the class and its objectsis exclusively via methods, and that's all the user of the class shouldever play with. 

Constructors and Instance Methods

Still, someone has to know what's in the object. And that someone isthe class. It implements methods that the programmer uses to accessthe object. Here's how to implement the Person class using the standardhash-ref-as-an-object idiom. We'll make a class method called new() toact as the constructor, and three object methods called name(), age(), andpeers() to get at per-object data hidden away in our anonymous hash.

    package Person;    use strict;
    ##################################################    ## the object constructor (simplistic version)  ##    ##################################################    sub new {        my $self  = {};        $self->{NAME}   = undef;        $self->{AGE}    = undef;        $self->{PEERS}  = [];        bless($self);           # but see below        return $self;    }
    ##############################################    ## methods to access per-object data        ##    ##                                          ##    ## With args, they set the value.  Without  ##    ## any, they only retrieve it/them.         ##    ##############################################
    sub name {        my $self = shift;        if (@_) { $self->{NAME} = shift }        return $self->{NAME};    }
    sub age {        my $self = shift;        if (@_) { $self->{AGE} = shift }        return $self->{AGE};    }
    sub peers {        my $self = shift;        if (@_) { @{ $self->{PEERS} } = @_ }        return @{ $self->{PEERS} };    }
    1;  # so the require or use succeeds
We've created three methods to access an object's data, name(), age(),and peers(). These are all substantially similar. If called with anargument, they set the appropriate field; otherwise they return thevalue held by that field, meaning the value of that hash key. 

Planning for the Future: Better Constructors

Even though at this point you may not even know what it means, somedayyou're going to worry about inheritance. (You can safely ignore thisfor now and worry about it later if you'd like.) To ensure that thisall works out smoothly, you must use the double-argument form of bless().The second argument is the class into which the referent will be blessed.By not assuming our own class as the default second argument and insteadusing the class passed into us, we make our constructor inheritable.

While we're at it, let's make our constructor a bit more flexible.Rather than being uniquely a class method, we'll set it up so thatit can be called as either a class method or an objectmethod. That way you can say:

    $me  = Person->new();    $him = $me->new();
To do this, all we have to do is check whether what was passed inwas a reference or not. If so, we were invoked as an object method,and we need to extract the package (class) using the ref() function.If not, we just use the string passed in as the package namefor blessing our referent.

    sub new {        my $proto = shift;        my $class = ref($proto) || $proto;        my $self  = {};        $self->{NAME}   = undef;        $self->{AGE}    = undef;        $self->{PEERS}  = [];        bless ($self, $class);        return $self;    }
That's about all there is for constructors. These methods bring objectsto life, returning neat little opaque bundles to the user to be used insubsequent method calls. 

Destructors

Every story has a beginning and an end. The beginning of the object'sstory is its constructor, explicitly called when the object comes intoexistence. But the ending of its story is the destructor, a methodimplicitly called when an object leaves this life. Any per-objectclean-up code is placed in the destructor, which must (in Perl) be calledDESTROY.

If constructors can have arbitrary names, then why not destructors?Because while a constructor is explicitly called, a destructor is not.Destruction happens automatically via Perl's garbage collection (GC)system, which is a quick but somewhat lazy reference-based GC system.To know what to call, Perl insists that the destructor be named DESTROY.Perl's notion of the right time to call a destructor is not well-definedcurrently, which is why your destructors should not rely on when they arecalled.

Why is DESTROY in all caps? Perl on occasion uses purely uppercasefunction names as a convention to indicate that the function willbe automatically called by Perl in some way. Others that are calledimplicitly include BEGIN, END, AUTOLOAD, plus all methods used bytied objects, described in the perltie manpage.

In really good object-oriented programming languages, the user doesn'tcare when the destructor is called. It just happens when it's supposedto. In low-level languages without any GC at all, there's no way todepend on this happening at the right time, so the programmer mustexplicitly call the destructor to clean up memory and state, crossingtheir fingers that it's the right time to do so. Unlike C++, anobject destructor is nearly never needed in Perl, and even when it is,explicit invocation is uncalled for. In the case of our Person class,we don't need a destructor because Perl takes care of simple matterslike memory deallocation.

The only situation where Perl's reference-based GC won't work iswhen there's a circularity in the data structure, such as:

    $this->{WHATEVER} = $this;
In that case, you must delete the self-reference manually if you expectyour program not to leak memory. While admittedly error-prone, this isthe best we can do right now. Nonetheless, rest assured that when yourprogram is finished, its objects' destructors are all duly called.So you are guaranteed that an object eventually gets properlydestroyed, except in the unique case of a program that never exits.(If you're running Perl embedded in another application, this full GCpass happens a bit more frequently---whenever a thread shuts down.) 

Other Object Methods

The methods we've talked about so far have either been constructors orelse simple ``data methods'', interfaces to data stored in the object.These are a bit like an object's data members in the C++ world, exceptthat strangers don't access them as data. Instead, they should onlyaccess the object's data indirectly via its methods. This is animportant rule: in Perl, access to an object's data should onlybe made through methods.

Perl doesn't impose restrictions on who gets to use which methods.The public-versus-private distinction is by convention, not syntax.(Well, unless you use the Alias module described below inthe section on /"Data Members as Variables.) Occasionally you'll see method names beginning or endingwith an underscore or two. This marking is a convention indicatingthat the methods are private to that class alone and sometimes to itsclosest acquaintances, its immediate subclasses. But this distinctionis not enforced by Perl itself. It's up to the programmer to behave.

There's no reason to limit methods to those that simply access data.Methods can do anything at all. The key point is that they're invokedagainst an object or a class. Let's say we'd like object methods thatdo more than fetch or set one particular field.

    sub exclaim {        my $self = shift;        return sprintf "Hi, I'm %s, age %d, working with %s",            $self->{NAME}, $self->{AGE}, join(", ", $self->{PEERS});    }
Or maybe even one like this:

    sub happy_birthday {        my $self = shift;        return ++$self->{AGE};    }
Some might argue that one should go at these this way:

    sub exclaim {        my $self = shift;        return sprintf "Hi, I'm %s, age %d, working with %s",            $self->name, $self->age, join(", ", $self->peers);    }
    sub happy_birthday {        my $self = shift;        return $self->age( $self->age() + 1 );    }
But since these methods are all executing in the class itself, thismay not be critical. There are tradeoffs to be made. Using directhash access is faster (about an order of magnitude faster, in fact), andit's more convenient when you want to interpolate in strings. But usingmethods (the external interface) internally shields not just the users ofyour class but even you yourself from changes in your data representation. 

Class Data

What about ``class data'', data items common to each object in a class?What would you want that for? Well, in your Person class, you mightlike to keep track of the total people alive. How do you implement that?

You could make it a global variable called $Person::Census. But aboutonly reason you'd do that would be if you wanted people to be able toget at your class data directly. They could just say $Person::Censusand play around with it. Maybe this is ok in your design scheme.You might even conceivably want to make it an exported variable. To beexportable, a variable must be a (package) global. If this were atraditional module rather than an object-oriented one, you might do that.

While this approach is expected in most traditional modules, it'sgenerally considered rather poor form in most object modules. In anobject module, you should set up a protective veil to separate interfacefrom implementation. So provide a class method to access class datajust as you provide object methods to access object data.

So, you could still keep $Census as a package global and rely uponothers to honor the contract of the module and therefore not play aroundwith its implementation. You could even be supertricky and make $Census atied object as described in the perltie manpage, thereby intercepting all accesses.

But more often than not, you just want to make your class data afile-scoped lexical. To do so, simply put this at the top of the file:

    my $Census = 0;
Even though the scope of a my() normally expires when the block in whichit was declared is done (in this case the whole file being required orused), Perl's deep binding of lexical variables guarantees that thevariable will not be deallocated, remaining accessible to functionsdeclared within that scope. This doesn't work with global variablesgiven temporary values via local(), though.

Irrespective of whether you leave $Census a package global or makeit instead a file-scoped lexical, you should make thesechanges to your Person::new() constructor:

    sub new {        my $proto = shift;        my $class = ref($proto) || $proto;        my $self  = {};        $Census++;        $self->{NAME}   = undef;        $self->{AGE}    = undef;        $self->{PEERS}  = [];        bless ($self, $class);        return $self;    }
    sub population {        return $Census;    }
Now that we've done this, we certainly do need a destructor so thatwhen Person is destroyed, the $Census goes down. Here's howthis could be done:

    sub DESTROY { --$Census }
Notice how there's no memory to deallocate in the destructor? That'ssomething that Perl takes care of for you all by itself. 

Accessing Class Data

It turns out that this is not really a good way to go about handlingclass data. A good scalable rule is that you must never reference classdata directly from an object method. Otherwise you aren't building ascalable, inheritable class. The object must be the rendezvous pointfor all operations, especially from an object method. The globals(class data) would in some sense be in the ``wrong'' package in yourderived classes. In Perl, methods execute in the context of the classthey were defined in, not that of the object that triggered them.Therefore, namespace visibility of package globals in methods is unrelatedto inheritance.

Got that? Maybe not. Ok, let's say that some other class ``borrowed''(well, inherited) the DESTROY method as it was defined above. When thoseobjects are destroyed, the original $Census variable will be altered,not the one in the new class's package namespace. Perhaps this is whatyou want, but probably it isn't.

Here's how to fix this. We'll store a reference to the data in thevalue accessed by the hash key ``_CENSUS''. Why the underscore? Well,mostly because an initial underscore already conveys strong feelingsof magicalness to a C programmer. It's really just a mnemonic deviceto remind ourselves that this field is special and not to be used asa public data member in the same way that NAME, AGE, and PEERS are.(Because we've been developing this code under the strict pragma, priorto perl version 5.004 we'll have to quote the field name.)

    sub new {        my $proto = shift;        my $class = ref($proto) || $proto;        my $self  = {};        $self->{NAME}     = undef;        $self->{AGE}      = undef;        $self->{PEERS}    = [];        # "private" data        $self->{"_CENSUS"} = \$Census;        bless ($self, $class);        ++ ${ $self->{"_CENSUS"} };        return $self;    }
    sub population {        my $self = shift;        if (ref $self) {            return ${ $self->{"_CENSUS"} };        } else {            return $Census;        }    }
    sub DESTROY {        my $self = shift;        -- ${ $self->{"_CENSUS"} };    }
 

Debugging Methods

It's common for a class to have a debugging mechanism. For example,you might want to see when objects are created or destroyed. To do that,add a debugging variable as a file-scoped lexical. For this, we'll pullin the standard Carp module to emit our warnings and fatal messages.That way messages will come out with the caller's filename andline number instead of our own; if we wanted them to be from our ownperspective, we'd just use die() and warn() directly instead of croak()and carp() respectively.

    use Carp;    my $Debugging = 0;
Now add a new class method to access the variable.

    sub debug {        my $class = shift;        if (ref $class)  { confess "Class method called as object method" }        unless (@_ == 1) { confess "usage: CLASSNAME->debug(level)" }        $Debugging = shift;    }
Now fix up DESTROY to murmur a bit as the moribund object expires:

    sub DESTROY {        my $self = shift;        if ($Debugging) { carp "Destroying $self " . $self->name }        -- ${ $self->{"_CENSUS"} };    }
One could conceivably make a per-object debug state. Thatway you could call both of these:

    Person->debug(1);   # entire class    $him->debug(1);     # just this object
To do so, we need our debugging method to be a ``bimodal'' one, one thatworks on both classes and objects. Therefore, adjust the debug()and DESTROY methods as follows:

    sub debug {        my $self = shift;        confess "usage: thing->debug(level)"    unless @_ == 1;        my $level = shift;        if (ref($self))  {            $self->{"_DEBUG"} = $level;         # just myself        } else {            $Debugging        = $level;         # whole class        }    }
    sub DESTROY {        my $self = shift;        if ($Debugging || $self->{"_DEBUG"}) {            carp "Destroying $self " . $self->name;        }        -- ${ $self->{"_CENSUS"} };    }
What happens if a derived class (which we'll call Employee) inheritsmethods from this Person base class? Then Employee->debug(), when calledas a class method, manipulates $Person::Debugging not $Employee::Debugging. 

Class Destructors

The object destructor handles the death of each distinct object. But sometimesyou want a bit of cleanup when the entire class is shut down, whichcurrently only happens when the program exits. To make such aclass destructor, create a function in that class's package namedEND. This works just like the END function in traditional modules,meaning that it gets called whenever your program exits unless it execsor dies of an uncaught signal. For example,

    sub END {        if ($Debugging) {            print "All persons are going away now.\n";        }    }
When the program exits, all the class destructors (END functions) arebe called in the opposite order that they were loaded in (LIFO order). 

Documenting the Interface

And there you have it: we've just shown you the implementation of thisPerson class. Its interface would be its documentation. Usually thismeans putting it in pod ("plain old documentation") format right therein the same file. In our Person example, we would place the followingdocs anywhere in the Person.pm file. Even though it looks mostly likecode, it's not. It's embedded documentation such as would be used bythe pod2man, pod2html, or pod2text programs. The Perl compiler ignorespods entirely, just as the translators ignore code. Here's an example ofsome pods describing the informal interface:

    =head1 NAME
    Person - class to implement people
    =head1 SYNOPSIS
     use Person;
     #################     # class methods #     #################     $ob    = Person->new;     $count = Person->population;
     #######################     # object data methods #     #######################
     ### get versions ###         $who   = $ob->name;         $years = $ob->age;         @pals  = $ob->peers;
     ### set versions ###         $ob->name("Jason");         $ob->age(23);         $ob->peers( "Norbert", "Rhys", "Phineas" );
     ########################     # other object methods #     ########################
     $phrase = $ob->exclaim;     $ob->happy_birthday;
    =head1 DESCRIPTION
    The Person class implements dah dee dah dee dah....
That's all there is to the matter of interface versus implementation.A programmer who opens up the module and plays around with all the privatelittle shiny bits that were safely locked up behind the interface contracthas voided the warranty, and you shouldn't worry about their fate. 

Aggregation

Suppose you later want to change the class to implement better names.Perhaps you'd like to support both given names (called Christian names,irrespective of one's religion) and family names (called surnames), plusnicknames and titles. If users of your Person class have been properlyaccessing it through its documented interface, then you can easily changethe underlying implementation. If they haven't, then they lose andit's their fault for breaking the contract and voiding their warranty.

To do this, we'll make another class, this one called Fullname. What'sthe Fullname class look like? To answer that question, you have tofirst figure out how you want to use it. How about we use it this way:

    $him = Person->new();    $him->fullname->title("St");    $him->fullname->christian("Thomas");    $him->fullname->surname("Aquinas");    $him->fullname->nickname("Tommy");    printf "His normal name is %s\n", $him->name;    printf "But his real name is %s\n", $him->fullname->as_string;
Ok. To do this, we'll change Person::new() so that it supportsa full name field this way:

    sub new {        my $proto = shift;        my $class = ref($proto) || $proto;        my $self  = {};        $self->{FULLNAME} = Fullname->new();        $self->{AGE}      = undef;        $self->{PEERS}    = [];        $self->{"_CENSUS"} = \$Census;        bless ($self, $class);        ++ ${ $self->{"_CENSUS"} };        return $self;    }
    sub fullname {        my $self = shift;        return $self->{FULLNAME};    }
Then to support old code, define Person::name() this way:

    sub name {        my $self = shift;        return $self->{FULLNAME}->nickname(@_)          ||   $self->{FULLNAME}->christian(@_);    }
Here's the Fullname class. We'll use the same techniqueof using a hash reference to hold data fields, and methodsby the appropriate name to access them:

    package Fullname;    use strict;
    sub new {        my $proto = shift;        my $class = ref($proto) || $proto;        my $self  = {            TITLE       => undef,            CHRISTIAN   => undef,            SURNAME     => undef,            NICK        => undef,        };        bless ($self, $class);        return $self;    }
    sub christian {        my $self = shift;        if (@_) { $self->{CHRISTIAN} = shift }        return $self->{CHRISTIAN};    }
    sub surname {        my $self = shift;        if (@_) { $self->{SURNAME} = shift }        return $self->{SURNAME};    }
    sub nickname {        my $self = shift;        if (@_) { $self->{NICK} = shift }        return $self->{NICK};    }
    sub title {        my $self = shift;        if (@_) { $self->{TITLE} = shift }        return $self->{TITLE};    }
    sub as_string {        my $self = shift;        my $name = join(" ", @$self{'CHRISTIAN', 'SURNAME'});        if ($self->{TITLE}) {            $name = $self->{TITLE} . " " . $name;        }        return $name;    }
    1;
Finally, here's the test program:

    #!/usr/bin/perl -w    use strict;    use Person;    sub END { show_census() }
    sub show_census ()  {        printf "Current population: %d\n", Person->population;    }
    Person->debug(1);
    show_census();
    my $him = Person->new();
    $him->fullname->christian("Thomas");    $him->fullname->surname("Aquinas");    $him->fullname->nickname("Tommy");    $him->fullname->title("St");    $him->age(1);
    printf "%s is really %s.\n", $him->name, $him->fullname;    printf "%s's age: %d.\n", $him->name, $him->age;    $him->happy_birthday;    printf "%s's age: %d.\n", $him->name, $him->age;
    show_census();
 

Inheritance

Object-oriented programming systems all support some notion ofinheritance. Inheritance means allowing one class to piggy-back ontop of another one so you don't have to write the same code again andagain. It's about software reuse, and therefore related to Laziness,the principal virtue of a programmer. (The import/export mechanisms intraditional modules are also a form of code reuse, but a simpler one thanthe true inheritance that you find in object modules.)

Sometimes the syntax of inheritance is built into the core of thelanguage, and sometimes it's not. Perl has no special syntax forspecifying the class (or classes) to inherit from. Instead, it's allstrictly in the semantics. Each package can have a variable called @ISA,which governs (method) inheritance. If you try to call a method on anobject or class, and that method is not found in that object's package,Perl then looks to @ISA for other packages to go looking through insearch of the missing method.

Like the special per-package variables recognized by Exporter (such as@EXPORT, @EXPORT_OK, @EXPORT_FAIL, %EXPORT_TAGS, and $VERSION), the @ISAarray must be a package-scoped global and not a file-scoped lexicalcreated via my(). Most classes have just one item in their @ISA array.In this case, we have what's called ``single inheritance'', or SI for short.

Consider this class:

    package Employee;    use Person;    @ISA = ("Person");    1;
Not a lot to it, eh? All it's doing so far is loading in anotherclass and stating that this one will inherit methods from thatother class if need be. We have given it none of its own methods.We rely upon an Employee to behave just like a Person.

Setting up an empty class like this is called the ``empty subclass test'';that is, making a derived class that does nothing but inherit from abase class. If the original base class has been designed properly,then the new derived class can be used as a drop-in replacement for theold one. This means you should be able to write a program like this:

    use Employee;    my $empl = Employee->new();    $empl->name("Jason");    $empl->age(23);    printf "%s is age %d.\n", $empl->name, $empl->age;
By proper design, we mean always using the two-argument form of bless(),avoiding direct access of global data, and not exporting anything. If youlook back at the Person::new() function we defined above, we were carefulto do that. There's a bit of package data used in the constructor,but the reference to this is stored on the object itself and all othermethods access package data via that reference, so we should be ok.

What do we mean by the Person::new() function -- isn't that actuallya method? Well, in principle, yes. A method is just a function thatexpects as its first argument a class name (package) or object(blessed reference). Person::new() is the function that both thePerson->new() method and the Employee->new() method endup calling. Understand that while a method call looks a lot like afunction call, they aren't really quite the same, and if you treat themas the same, you'll very soon be left with nothing but broken programs.First, the actual underlying calling conventions are different: methodcalls get an extra argument. Second, function calls don't do inheritance,but methods do.

        Method Call             Resulting Function Call        -----------             ------------------------        Person->new()           Person::new("Person")        Employee->new()         Person::new("Employee")
So don't use function calls when you mean to call a method.

If an employee is just a Person, that's not all too very interesting.So let's add some other methods. We'll give our employeedata fields to access their salary, their employee ID, and theirstart date.

If you're getting a little tired of creating all these nearly identicalmethods just to get at the object's data, do not despair. Later,we'll describe several different convenience mechanisms for shorteningthis up. Meanwhile, here's the straight-forward way:

    sub salary {        my $self = shift;        if (@_) { $self->{SALARY} = shift }        return $self->{SALARY};    }
    sub id_number {        my $self = shift;        if (@_) { $self->{ID} = shift }        return $self->{ID};    }
    sub start_date {        my $self = shift;        if (@_) { $self->{START_DATE} = shift }        return $self->{START_DATE};    }
 

Overridden Methods

What happens when both a derived class and its base class have the samemethod defined? Well, then you get the derived class's version of thatmethod. For example, let's say that we want the peers() method called onan employee to act a bit differently. Instead of just returning the listof peer names, let's return slightly different strings. So doing this:

    $empl->peers("Peter", "Paul", "Mary");    printf "His peers are: %s\n", join(", ", $empl->peers);
will produce:

    His peers are: PEON=PETER, PEON=PAUL, PEON=MARY
To do this, merely add this definition into the Employee.pm file:

    sub peers {        my $self = shift;        if (@_) { @{ $self->{PEERS} } = @_ }        return map { "PEON=\U$_" } @{ $self->{PEERS} };    }
There, we've just demonstrated the high-falutin' concept known in certaincircles as polymorphism. We've taken on the form and behaviour ofan existing object, and then we've altered it to suit our own purposes.This is a form of Laziness. (Getting polymorphed is also what happenswhen the wizard decides you'd look better as a frog.)

Every now and then you'll want to have a method call trigger both itsderived class (also known as ``subclass") version as well as its base class(also known as ``superclass") version. In practice, constructors anddestructors are likely to want to do this, and it probably also makessense in the debug() method we showed previously.

To do this, add this to Employee.pm:

    use Carp;    my $Debugging = 0;
    sub debug {        my $self = shift;        confess "usage: thing->debug(level)"    unless @_ == 1;        my $level = shift;        if (ref($self))  {            $self->{"_DEBUG"} = $level;        } else {            $Debugging = $level;            # whole class        }        Person::debug($self, $Debugging);   # don't really do this    }
As you see, we turn around and call the Person package's debug() function.But this is far too fragile for good design. What if Person doesn'thave a debug() function, but is inheriting its debug() methodfrom elsewhere? It would have been slightly better to say

    Person->debug($Debugging);
But even that's got too much hard-coded. It's somewhat better to say

    $self->Person::debug($Debugging);
Which is a funny way to say to start looking for a debug() method upin Person. This strategy is more often seen on overridden object methodsthan on overridden class methods.

There is still something a bit off here. We've hard-coded oursuperclass's name. This in particular is bad if you change which classesyou inherit from, or add others. Fortunately, the pseudoclass SUPERcomes to the rescue here.

    $self->SUPER::debug($Debugging);
This way it starts looking in my class's @ISA. This only makes sensefrom within a method call, though. Don't try to access anythingin SUPER:: from anywhere else, because it doesn't exist outsidean overridden method call.

Things are getting a bit complicated here. Have we done anythingwe shouldn't? As before, one way to test whether we're designinga decent class is via the empty subclass test. Since we already havean Employee class that we're trying to check, we'd better get a newempty subclass that can derive from Employee. Here's one:

    package Boss;    use Employee;        # :-)    @ISA = qw(Employee);
And here's the test program:

    #!/usr/bin/perl -w    use strict;    use Boss;    Boss->debug(1);
    my $boss = Boss->new();
    $boss->fullname->title("Don");    $boss->fullname->surname("Pichon Alvarez");    $boss->fullname->christian("Federico Jesus");    $boss->fullname->nickname("Fred");
    $boss->age(47);    $boss->peers("Frank", "Felipe", "Faust");
    printf "%s is age %d.\n", $boss->fullname, $boss->age;    printf "His peers are: %s\n", join(", ", $boss->peers);
Running it, we see that we're still ok. If you'd like to dump out yourobject in a nice format, somewhat like the way the `x' command works inthe debugger, you could use the Data::Dumper module from CPAN this way:

    use Data::Dumper;    print "Here's the boss:\n";    print Dumper($boss);
Which shows us something like this:

    Here's the boss:    $VAR1 = bless( {         _CENSUS => \1,         FULLNAME => bless( {                              TITLE => 'Don',                              SURNAME => 'Pichon Alvarez',                              NICK => 'Fred',                              CHRISTIAN => 'Federico Jesus'                            }, 'Fullname' ),         AGE => 47,         PEERS => [                    'Frank',                    'Felipe',                    'Faust'                  ]       }, 'Boss' );
Hm.... something's missing there. What about the salary, start date,and ID fields? Well, we never set them to anything, even undef, so theydon't show up in the hash's keys. The Employee class has no new() methodof its own, and the new() method in Person doesn't know about Employees.(Nor should it: proper OO design dictates that a subclass be allowed toknow about its immediate superclass, but never vice-versa.) So let'sfix up Employee::new() this way:

    sub new {        my $proto = shift;        my $class = ref($proto) || $proto;        my $self  = $class->SUPER::new();        $self->{SALARY}        = undef;        $self->{ID}            = undef;        $self->{START_DATE}    = undef;        bless ($self, $class);          # reconsecrate        return $self;    }
Now if you dump out an Employee or Boss object, you'll findthat new fields show up there now. 

Multiple Inheritance

Ok, at the risk of confusing beginners and annoying OO gurus, it'stime to confess that Perl's object system includes that controversialnotion known as multiple inheritance, or MI for short. All this meansis that rather than having just one parent class who in turn mightitself have a parent class, etc., that you can directly inherit fromtwo or more parents. It's true that some uses of MI can get you intotrouble, although hopefully not quite so much trouble with Perl as withdubiously-OO languages like C++.

The way it works is actually pretty simple: just put more than one packagename in your @ISA array. When it comes time for Perl to go findingmethods for your object, it looks at each of these packages in order.Well, kinda. It's actually a fully recursive, depth-first order.Consider a bunch of @ISA arrays like this:

    @First::ISA    = qw( Alpha );    @Second::ISA   = qw( Beta );    @Third::ISA    = qw( First Second );
If you have an object of class Third:

    my $ob = Third->new();    $ob->spin();
How do we find a spin() method (or a new() method for that matter)?Because the search is depth-first, classes will be looked upin the following order: Third, First, Alpha, Second, and Beta.

In practice, few class modules have been seen that actuallymake use of MI. One nearly always chooses simple containership ofone class within another over MI. That's why our Personobject contained a Fullname object. That doesn't meanit was one.

However, there is one particular area where MI in Perl is rampant:borrowing another class's class methods. This is rather common,especially with some bundled ``objectless'' classes,like Exporter, DynaLoader, AutoLoader, and SelfLoader. These classesdo not provide constructors; they exist only so you may inherit theirclass methods. (It's not entirely clear why inheritance was donehere rather than traditional module importation.)

For example, here is the POSIX module's @ISA:

    package POSIX;    @ISA = qw(Exporter DynaLoader);
The POSIX module isn't really an object module, but then,neither are Exporter or DynaLoader. They're just lending theirclasses' behaviours to POSIX.

Why don't people use MI for object methods much? One reason is thatit can have complicated side-effects. For one thing, your inheritancegraph (no longer a tree) might converge back to the same base class.Although Perl guards against recursive inheritance, merely having parentswho are related to each other via a common ancestor, incestuous thoughit sounds, is not forbidden. What if in our Third class shown above wewanted its new() method to also call both overridden constructors in itstwo parent classes? The SUPER notation would only find the first one.Also, what about if the Alpha and Beta classes both had a common ancestor,like Nought? If you kept climbing up the inheritance tree callingoverridden methods, you'd end up calling Nought::new() twice,which might well be a bad idea. 

UNIVERSAL: The Root of All Objects

Wouldn't it be convenient if all objects were rooted at some ultimatebase class? That way you could give every object common methods withouthaving to go and add it to each and every @ISA. Well, it turns out thatyou can. You don't see it, but Perl tacitly and irrevocably assumesthat there's an extra element at the end of @ISA: the class UNIVERSAL.In version 5.003, there were no predefined methods there, but you could putwhatever you felt like into it.

However, as of version 5.004 (or some subversive releases, like 5.003_08),UNIVERSAL has some methods in it already. These are builtin to your Perlbinary, so they don't take any extra time to load. Predefined methodsinclude isa(), can(), and VERSION(). isa() tells you whether an object orclass ``is'' another one without having to traverse the hierarchy yourself:

   $has_io = $fd->isa("IO::Handle");   $itza_handle = IO::Socket->isa("IO::Handle");
The can() method, called against that object or class, reports backwhether its string argument is a callable method name in that class.In fact, it gives you back a function reference to that method:

   $his_print_method = $obj->can('as_string');
Finally, the VERSION method checks whether the class (or the object'sclass) has a package global called $VERSION that's high enough, as in:

    Some_Module->VERSION(3.0);    $his_vers = $ob->VERSION();
However, we don't usually call VERSION ourselves. (Remember that an alluppercase function name is a Perl convention that indicates that thefunction will be automatically used by Perl in some way.) In this case,it happens when you say

    use Some_Module 3.0;
If you wanted to add version checking to your Person class explainedabove, just add this to Person.pm:

    use vars qw($VERSION);    $VERSION = '1.1';
and then in Employee.pm could you can say

    use Employee 1.1;
And it would make sure that you have at least that version number orhigher available. This is not the same as loading in that exact versionnumber. No mechanism currently exists for concurrent installation ofmultiple versions of a module. Lamentably. 

Alternate Object Representations

Nothing requires objects to be implemented as hash references. An objectcan be any sort of reference so long as its referent has been suitablyblessed. That means scalar, array, and code references are also fairgame.

A scalar would work if the object has only one datum to hold. An arraywould work for most cases, but makes inheritance a bit dodgy becauseyou have to invent new indices for the derived classes. 

Arrays as Objects

If the user of your class honors the contract and sticks to the advertisedinterface, then you can change its underlying interface if you feellike it. Here's another implementation that conforms to the sameinterface specification. This time we'll use an array referenceinstead of a hash reference to represent the object.

    package Person;    use strict;
    my($NAME, $AGE, $PEERS) = ( 0 .. 2 );
    ############################################    ## the object constructor (array version) ##    ############################################    sub new {        my $self = [];        $self->[$NAME]   = undef;  # this is unnecessary        $self->[$AGE]    = undef;  # as is this        $self->[$PEERS]  = [];     # but this isn't, really        bless($self);        return $self;    }
    sub name {        my $self = shift;        if (@_) { $self->[$NAME] = shift }        return $self->[$NAME];    }
    sub age {        my $self = shift;        if (@_) { $self->[$AGE] = shift }        return $self->[$AGE];    }
    sub peers {        my $self = shift;        if (@_) { @{ $self->[$PEERS] } = @_ }        return @{ $self->[$PEERS] };    }
    1;  # so the require or use succeeds
You might guess that the array access would be a lot faster than thehash access, but they're actually comparable. The array is a littlebit faster, but not more than ten or fifteen percent, even when youreplace the variables above like $AGE with literal numbers, like 1.A bigger difference between the two approaches can be found in memory use.A hash representation takes up more memory than an array representationbecause you have to allocate memory for the keys as well as for the values.However, it really isn't that bad, especially since as of version 5.004,memory is only allocated once for a given hash key, no matter how manyhashes have that key. It's expected that sometime in the future, eventhese differences will fade into obscurity as more efficient underlyingrepresentations are devised.

Still, the tiny edge in speed (and somewhat larger one in memory)is enough to make some programmers choose an array representationfor simple classes. There's still a little problem withscalability, though, because later in life when you feellike creating subclasses, you'll find that hashes just workout better. 

Closures as Objects

Using a code reference to represent an object offers some fascinatingpossibilities. We can create a new anonymous function (closure) whoalone in all the world can see the object's data. This is because weput the data into an anonymous hash that's lexically visible only tothe closure we create, bless, and return as the object. This object'smethods turn around and call the closure as a regular subroutine call,passing it the field we want to affect. (Yes,the double-function call is slow, but if you wanted fast, you wouldn'tbe using objects at all, eh? :-)

Use would be similar to before:

    use Person;    $him = Person->new();    $him->name("Jason");    $him->age(23);    $him->peers( [ "Norbert", "Rhys", "Phineas" ] );    printf "%s is %d years old.\n", $him->name, $him->age;    print "His peers are: ", join(", ", @{$him->peers}), "\n";
but the implementation would be radically, perhaps even sublimelydifferent:

    package Person;
    sub new {         my $that  = shift;         my $class = ref($that) || $that;         my $self = {            NAME  => undef,            AGE   => undef,            PEERS => [],         };         my $closure = sub {            my $field = shift;            if (@_) { $self->{$field} = shift }            return    $self->{$field};        };        bless($closure, $class);        return $closure;    }
    sub name   { &{ $_[0] }("NAME",  @_[ 1 .. $#_ ] ) }    sub age    { &{ $_[0] }("AGE",   @_[ 1 .. $#_ ] ) }    sub peers  { &{ $_[0] }("PEERS", @_[ 1 .. $#_ ] ) }
    1;
Because this object is hidden behind a code reference, it's probably a bitmysterious to those whose background is more firmly rooted in standardprocedural or object-based programming languages than in functionalprogramming languages whence closures derive. The objectcreated and returned by the new() method is itself not a data referenceas we've seen before. It's an anonymous code reference that has withinit access to a specific version (lexical binding and instantiation)of the object's data, which are stored in the private variable $self.Although this is the same function each time, it contains a differentversion of $self.

When a method like $him->name("Jason") is called, its implicitzeroth argument is the invoking object---just as it is with all methodcalls. But in this case, it's our code reference (something like afunction pointer in C++, but with deep binding of lexical variables).There's not a lot to be done with a code reference beyond calling it, sothat's just what we do when we say &{$_[0]}. This is just a regularfunction call, not a method call. The initial argument is the string``NAME'', and any remaining arguments are whatever had been passed to themethod itself.

Once we're executing inside the closure that had been created in new(),the $self hash reference suddenly becomes visible. The closure grabsits first argument ("NAME'' in this case because that's what the name()method passed it), and uses that string to subscript into the privatehash hidden in its unique version of $self.

Nothing under the sun will allow anyone outside the executing method tobe able to get at this hidden data. Well, nearly nothing. You couldsingle step through the program using the debugger and find out thepieces while you're in the method, but everyone else is out of luck.

There, if that doesn't excite the Scheme folks, then I just don't knowwhat will. Translation of this technique into C++, Java, or any otherbraindead-static language is left as a futile exercise for aficionadosof those camps.

You could even add a bit of nosiness via the caller() function andmake the closure refuse to operate unless called via its own package.This would no doubt satisfy certain fastidious concerns of programmingpolice and related puritans.

If you were wondering when Hubris, the third principle virtue of aprogrammer, would come into play, here you have it. (More seriously,Hubris is just the pride in craftsmanship that comes from having writtena sound bit of well-designed code.) 

AUTOLOAD: Proxy Methods

Autoloading is a way to intercept calls to undefined methods. An autoloadroutine may choose to create a new function on the fly, either loadedfrom disk or perhaps just eval()ed right there. This define-on-the-flystrategy is why it's called autoloading.

But that's only one possible approach. Another one is to justhave the autoloaded method itself directly provide therequested service. When used in this way, you may thinkof autoloaded methods as ``proxy'' methods.

When Perl tries to call an undefined function in a particular packageand that function is not defined, it looks for a function inthat same package called AUTOLOAD. If one exists, it's calledwith the same arguments as the original function would have had.The fully-qualified name of the function is stored in that package'sglobal variable $AUTOLOAD. Once called, the function can do anythingit would like, including defining a new function by the right name, andthen doing a really fancy kind of goto right to it, erasing itselffrom the call stack.

What does this have to do with objects? After all, we keep talking aboutfunctions, not methods. Well, since a method is just a function withan extra argument and some fancier semantics about where it's found,we can use autoloading for methods, too. Perl doesn't start lookingfor an AUTOLOAD method until it has exhausted the recursive hunt upthrough @ISA, though. Some programmers have even been known to definea UNIVERSAL::AUTOLOAD method to trap unresolved method calls to anykind of object. 

Autoloaded Data Methods

You probably began to get a little suspicious about the duplicatedcode way back earlier when we first showed you the Person class, andthen later the Employee class. Each method used to access thehash fields looked virtually identical. This should have tickledthat great programming virtue, Impatience, but for the time,we let Laziness win out, and so did nothing. Proxy methods can curethis.

Instead of writing a new function every time we want a new data field,we'll use the autoload mechanism to generate (actually, mimic) methods onthe fly. To verify that we're accessing a valid member, we will checkagainst an _permitted (pronounced ``under-permitted") field, whichis a reference to a file-scoped lexical (like a C file static) hash of permitted fields in this recordcalled %fields. Why the underscore? For the same reason as the _CENSUSfield we once used: as a marker that means ``for internal use only''.

Here's what the module initialization code and classconstructor will look like when taking this approach:

    package Person;    use Carp;    use vars qw($AUTOLOAD);  # it's a package global
    my %fields = (        name        => undef,        age         => undef,        peers       => undef,    );
    sub new {        my $that  = shift;        my $class = ref($that) || $that;        my $self  = {            _permitted => \%fields,            %fields,        };        bless $self, $class;        return $self;    }
If we wanted our record to have default values, we could fill those inwhere current we have undef in the %fields hash.

Notice how we saved a reference to our class data on the object itself?Remember that it's important to access class data through the objectitself instead of having any method reference %fields directly, or elseyou won't have a decent inheritance.

The real magic, though, is going to reside in our proxy method, whichwill handle all calls to undefined methods for objects of class Person(or subclasses of Person). It has to be called AUTOLOAD. Again, it'sall caps because it's called for us implicitly by Perl itself, not bya user directly.

    sub AUTOLOAD {        my $self = shift;        my $type = ref($self)                    or croak "$self is not an object";
        my $name = $AUTOLOAD;        $name =~ s/.*://;   # strip fully-qualified portion
        unless (exists $self->{_permitted}->{$name} ) {            croak "Can't access `$name' field in class $type";        }
        if (@_) {            return $self->{$name} = shift;        } else {            return $self->{$name};        }    }
Pretty nifty, eh? All we have to do to add new data fieldsis modify %fields. No new functions need be written.

I could have avoided the _permitted field entirely, but Iwanted to demonstrate how to store a reference to class data on theobject so you wouldn't have to access that class datadirectly from an object method. 

Inherited Autoloaded Data Methods

But what about inheritance? Can we define our Employeeclass similarly? Yes, so long as we're careful enough.

Here's how to be careful:

    package Employee;    use Person;    use strict;    use vars qw(@ISA);    @ISA = qw(Person);
    my %fields = (        id          => undef,        salary      => undef,    );
    sub new {        my $that  = shift;        my $class = ref($that) || $that;        my $self = bless $that->SUPER::new(), $class;        my($element);        foreach $element (keys %fields) {            $self->{_permitted}->{$element} = $fields{$element};        }        @{$self}{keys %fields} = values %fields;        return $self;    }
Once we've done this, we don't even need to have anAUTOLOAD function in the Employee package, becausewe'll grab Person's version of that via inheritance,and it will all work out just fine. 

Metaclassical Tools

Even though proxy methods can provide a more convenient approach to makingmore struct-like classes than tediously coding up data methods asfunctions, it still leaves a bit to be desired. For one thing, it meansyou have to handle bogus calls that you don't mean to trap via your proxy.It also means you have to be quite careful when dealing with inheritance,as detailed above.

Perl programmers have responded to this by creating several differentclass construction classes. These metaclasses are classesthat create other classes. A couple worth looking at areClass::Struct and Alias. These and other related metaclasses can befound in the modules directory on CPAN. 

Class::Struct

One of the older ones is Class::Struct. In fact, its syntax andinterface were sketched out long before perl5 even solidified into are
 
ICM Bot detect detector