Objects in Perl
Why Objects
Objects make programming easier. We use objects to hide complex functions
and data types from the use of the function.
For example, suppose you want to have an interface between your program
and some database. This interface could take thousands of lines of
code, and be very complex internally. However, it need not look complex
to the user of the interface. Instead he is just given a few simple
calls like connect, fetch_array, etc.
Perl has many such packages available for use. Much of
the power of Perl is within these packages.
The Fraction Class
Here we will explore a very simple package; one that implements simple
fractions like 5/3 or 2/7. It stores the fraction as two numbers,
a top and a bottom. The package can make a new fraction, set the
value of a fraction, add to fractions together, and print a fraction.
The program that uses the fraction package is simple, and easy to read.
You can find the source code to the main program
and to the fraction class.
#!/usr/bin/perl -w
use Fraction;
$f1 = Fraction->new();
$f2 = Fraction->new();
$f1->set(5, 3);
$f2->set(2,5);
print "The fraction " . $f1->toString() . " + " . $f2->toString();
$f1->add($f2);
print " is " . $f1->toString() . "\n"; |
Start a new class
Make a name for this object. I'll call it 'Fraction'.
Make a file named 'Fraction.pm'. The first line of the file should
say
package Fraction;
This declares that all of the code in this file will use the namespace
Fraction.
A namespace is a set of code that call all access the same variables, and
that code using those variable names but not within the namespace cannot
use the variables. In this case, it means that any variable
like $age can be used within this file, but will not be effected
by any code outside the file. Namespaces keeps this object's code
from effecting the variables of other code.
Write the New function
An object in perl is really a hash of variables, all assigned to a namespace.
The new function is responsible for contructing the new hash, and assigning
to the namespace. It will be given as it's one parameter the name
of the class. Within the new function, you will use the 'bless' command.
Bless takes two arguments: the has, and the namespace. Bless
is somewhat like the cast function in C/C++/Java.
The new function should return the hash/array you just made. Having
the bless function as the last line of the new function causes the return
value of bless to be returned by new, which also works.
sub new {
my($class) = shift;
bless {
"top" => 0,
"bot" => 0
}, $class;
}
The operator => is really just a comma, but the Perl object people like
to use =>. The bless line could also be written
bless( {"top", 0, "bot", 0}, $class);
which makes it more clear that the first argument is just a hash (associative
array) and the second the name of a namespace.
Write More Functions
Given an object, we need functions to manipulate the object. Normally,
every function for the object goes in the same file. However, the
actual rule is that each function must be written in a file starting package
Fraction, and that file must have been use'd by the
calling file. It easiest just to do it all in the same file, however.
Every function is automatically given as the first parameter a reference
to the hash. Normally we call that $self.
sub set {
my($self) = shift;
my($newtop) = shift;
my($newbottom) = shift;
$self->{"top"} = $newtop;
$self->{"bot"} = $newbottom;
}
Writing even more functions
Often, you will want to access more than one member of a class from the
same function. In this example, you might want to add two Fractions
together. Generally, one of them will be self and the other will
be passes as an argument to the function. For example ...
sub add {
my($self) = shift;
my($f2) = shift;
my($top) = $self->{"top"};
my($otop) = $f2->{"top"};
my($bot) = $self->{"bot"};
my($obot) = $f2->{"bot"};
$self->set($top*$obot + $otop * $bot, $bot * $obot);
}
Finishing the Object
Here are to little tricks. It's generally a good idea to have a function
named toString, that takes no arguments (except self, of course) and
returns a string describing the object. This function is very useful
for debugging, and you will generally fund other uses also.
sub toString {
my($self) = shift;
my($top) = $self->{"top"};
my($bot) = $self->{"bot"};
return "$top / $bot";
}
Also, Perl requires that every file you will use return true
if it successfully loads. Therefore, every file defining an object
should have as it's last line
1;
That strange line tells the file that loaded the object that the object
was loaded successfully.
Using Objects
Given you have an object, it's important