Home Accessibility Courses Diary The Mouth Forum Resources Site Map About Us Contact
 
For 2023 (and 2024 ...) - we are now fully retired from IT training.
We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.

Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!

I am also active in many other area and still look after a lot of web sites - you can find an index ((here))
Object Orientation in Perl - First Steps

DEVELOPING TOWARDS OBJECT ORIENTATION IN PERL

Perl 5 has, perhaps, the most flexible Object Oriented facilities of any language - but they're also implemented at quite a low level which means you need to know quite a lot before you start using objects that others have written, and one heck of a lot before you start writing your own objects.

Here's a program that's calling in a Perl Module in a file called animal.pm, which contains subs called new and geteage. Clearly, the new sub returns some sort of variable that contains everything about an animal that has been entered (and in pracise, it's the address of a hash, which you'll see later). By returning this "contains everything" varriable in this way, Perl allows the geteage function to be called on the data with the author of this calling program not having to understand the internal workings and algorithm used ... which is good news as we really don't want every programmer to have to understand everything at the lowest level. Just like you don't have to know how to drive a bus just to make a journey on one!

So this article has two sections
   * Firstly of CALLING object
   * Secondly on CREATING YOUR OWN object types

THE STORY OF CALLING OBJECTS IN PERL

use animal;

$rover = new("Rover","Parrot",12,4);
$second = new("Reg","Elephant",73,1.1);

$ea1 = geteage($rover);
$ea2 = geteage($second);

print "Ages are $ea1 and $ea2\n";

See source code

The code above works brilliantly - but what if you want to use a whole lot of different modules, and there's a conflict between the sub names in each of them - for example, there could be a new sub in animal, and one in icecream and one in placename and one in trapeze ...

This is where a "package" comes in. In the next example of our calling code, we have called a different animal class in which the contents of the file have been declared to be in a package called "animal". Following a similar pattern, we could call in lots of modules / packages, ALL of which had a new sub and there would not be a conflict. Think of it like this - at school, there were 5 girls each called Emma in your class. And it got confusing until you started to refer to them as Emma Butler, Emma Bunton, Emma Woodhouse, Emma Watson and Emma Kirkby. So the package name is like a surname, with the sub name like a forename.

use animal;

$rover = animal::new
 ("Rover","Parrot",12,4);
$second = animal::new
 ("Reg","Elephant",73,1.1);

$ea1 = animal::geteage($rover);
$ea2 = animal::geteage($second);

print "Ages are $ea1 and $ea2\n";

See source code

The next step is that I might want to write a program that handles a whole lot of things to which similar - but not identical - concepts and algorithms apply. For example, Oxford Zoo has animals and staff ... and both animals and staff have "effective ages" that we want to report. However, the algorithm is different for a staff member and an animal, as most animals age rather faster than humans - a parrot ages (we guessed as we wrote this example) 4 times as fast.

In the code, we're now calling two different new functions and we're making up a list that we can traverse of all of our animals and staff. We have changed the way that the geteage sub is called, using the -> notation now, so that Perl can decide at run time what type of data it is handling each time through the loop, and call the appropriate code.

use animal;

$rover = beast::new
 ("Rover","Parrot",12,4);
$second = beast::new
 ("Reg","Elephant",73,1.1);
$gerald = staff::new("Gerald",50);
@team = ($rover,$second,$gerald);

foreach $tm(@team) {
 $ea1 = $tm->geteage();
 print "$tm --- Age is $ea1\n";
 }

See source code

Finally, we have tidied up the syntax of "new" as this is a construct we'll be using very often and we want to encourage it.

use animal;

$rover = new beast
 ("Rover","Parrot",12,4);
$second = new beast
 ("Reg","Elephant",73,1.1);
$gerald = new staff("Gerald",50);
@team = ($rover,$second,$gerald);

foreach $tm(@team) {
 $ea1 = $tm->geteage();
 print "$tm --- Age is $ea1\n";
 }

See source code

Here's what you see when you run that code:

Dorothy:p82 grahamellis$ perl ua
beast=HASH(0x801b50) --- Age is 48
beast=HASH(0x828e6c) --- Age is 80.3
staff=HASH(0x801d3c) --- Age is 50
Dorothy:p82 grahamellis$

THE STORY OF WRITING OBJECTS IN PERL

The examples above have only shown you a half of the code that you need for a complete application - but it's the part that you'll most commonly write since modules will be reused. A module author will typically canvas inputs from a potential user base and look to provide a series of subs in a form that's very suitable for a lot of people to use - that way, he'll get a lot of customers. At the same time, he'll look to limit the number of different subs he provides - both to make his own life easier with regards to maintainance, and to make life easier for his customers who'll not want a bewildering choice of options ((even though that is the Perl way!))

Here's the first example of a module called animal.pm - to go with the first source code test program above. The new sub saves each of the incoming parameters into a hash (which has been declared my to ensure that you get a different hash each time and don't just overwrite) and - as predicted above - we have returned the address of a hash.

Note the -> notation which lets you look at the contents of a variable that's contained within in an address variable (i.e. is pointed to) rather that the variable itself.

sub new {
 my ($name,$breed,$age,$hf) = @_;
 my %info;
 $info{name} = $name;
 $info{breed} = $breed;
 $info{age} = $age;
 $info{hf} = $hf;
 return \%info;
 }
sub geteage {
 my ($current) = @_;
 # Following comment shows alternative notation to ->
 # $$current{age} * $$current{hf};
 $current->{age} * $current->{hf};
 }
1;

See source code

In order to give each of the subs we use a package (family) name, we only need to add in a package statement. Then they're no longer members of the "main" family but - in this example - members of the "animal" family.

package animal;
sub new {
 my ($name,$breed,$age,$hf) = @_;
 my %info;
 $info{name} = $name;
 $info{breed} = $breed;
 $info{age} = $age;
 $info{hf} = $hf;
 return \%info;
 }
sub geteage {
 my ($current) = @_;
 $current->{age} * $current->{hf};
 }
1;

See source code

In the next development, we've defined two packages within the same module (and to aid the demonstration, we've renamed them too). Unlike some other languages, you are not limited in Perl to one package [class] definition per file, and it's good practise to place a series of closely related classes that will be used in the same applications and maintained by the same person / people into the same file.

By having subs of the same name in each of the packackes, we're doing something very clever because we're allowing the final versions of our user's code (above) to simply call a sub of a certain name, and the code will automatically work out which one is being referred to. For this to work (it's the -> on the call), each of the hashes needs to have some data associated with it to tell it what type of data it is, and the bless function does this - it returns the address of the hash, but in addition it returns the package name so that the calling code is told "this is a beast" or "this is a staff".

package beast;
sub new {
 my ($name,$breed,$age,$hf) = @_;
 my %info;
 $info{name} = $name;
 $info{breed} = $breed;
 $info{age} = $age;
 $info{hf} = $hf;
 bless \%info;
 }
sub geteage {
 my ($current) = @_;
 $current->{age} * $current->{hf};
 }
package staff;
sub new {
 my ($name,$age) = @_;
 my %info;
 $info{name} = $name;
 $info{age} = $age;
 bless \%info;
 }
sub geteage {
 my ($current) = @_;
 $current->{age} ;
 }
1;

See source code

Our final example corresponds with the final example of the calling code above. There's an extra parameter passed in to the new sub (not obvious from the earlier call) and this is the name of the class. It gives us extra flexibility in that we can return an "object" of any type now - which proves to be of huge benefit as we take Object Orientation on further.

package beast;
sub new {
 my ($class,$name,$breed,$age,$hf) = @_;
 my %info;
 $info{name} = $name;
 $info{breed} = $breed;
 $info{age} = $age;
 $info{hf} = $hf;
 bless \%info,$class;
 }
sub geteage {
 my ($current) = @_;
 $current->{age} * $current->{hf};
 }
package staff;
sub new {
 my ($class,$name,$age) = @_;
 my %info;
 $info{name} = $name;
 $info{age} = $age;
 bless \%info,$class;
 }
sub geteage {
 my ($current) = @_;
 $current->{age} ;
 }
1;

See source code

AND FURTHER ON

If you're going to be using a series of similar objects, then you'll be tempted to cut and paste the source code - PLEASE DO NOT. You can use a feature of most OO languages called interitance, in which you base one class on another and then simple state the relationship. This saves a lot of coding ... and a lot of maintainaince work too.

In Perl, you can define something called an AUTOLOAD sub that allows you to set and get a whole load pf propeties (and do a lot else too) without having to write a whole lot of extra subs.

Most OO languages (not Perl 5, though!) provide keywords such as private and protected and public which allow you to limit the access by the calling program directly to the elements of your code. Perl, however, assumes trust and assumes that everyone knows what they're doing as well.

If you're new to Perl and want help learning some of the basics, have a look elsewhere around this site where we have plenty of resources, or come on our Perl Programming course ... if you're already familiar with Perl, but need to get further into the Object Oriented matters that this article starts to introduce, you'll want our Perl for Larger Projects course.

See Perl Programming Course

See Perl for larger projects course




See also Perl for Larger Projects

Please note that articles in this section of our web site were current and correct to the best of our ability when published, but by the nature of our business may go out of date quite quickly. The quoting of a price, contract term or any other information in this area of our website is NOT an offer to supply now on those terms - please check back via our main web site

Related Material

Object Orientation and General technical topics - Object Orientation: Individual Objects
  [227] - ()
  [507] - ()
  [1543] - ()
  [1864] - ()
  [1925] - ()
  [2171] - ()
  [2173] - ()
  [2393] - ()
  [2651] - ()
  [3436] - ()
  [3721] - ()
  [4021] - ()
  [4448] - ()
  [4591] - ()
  [4650] - ()

Perl - Creating your own Classes
  [227] - ()
  [246] - ()
  [975] - ()
  [983] - ()
  [1320] - ()
  [1435] - ()
  [1664] - ()
  [1864] - ()
  [1925] - ()
  [2169] - ()
  [2834] - ()
  [2877] - ()
  [2969] - ()
  [3059] - ()
  [3098] - ()
  [3833] - ()
  [4607] - ()

Perl - More Objects
  [227] - ()
  [246] - ()
  [531] - ()
  [588] - ()
  [592] - ()
  [656] - ()
  [831] - ()
  [930] - ()
  [1217] - ()
  [1320] - ()
  [1435] - ()
  [1664] - ()
  [1665] - ()
  [1819] - ()
  [1949] - ()
  [2427] - ()
  [2651] - ()
  [2717] - ()
  [2811] - ()
  [2876] - ()
  [2972] - ()
  [3097] - ()
  [3098] - ()
  [3377] - ()
  [3581] - ()
  [3941] - ()
  [4096] - ()
  [4098] - ()
  [4356] - ()
  [4366] - ()

resource index - Perl
Solutions centre home page

You'll find shorter technical items at The Horse's Mouth and delegate's questions answered at the Opentalk forum.

At Well House Consultants, we provide training courses on subjects such as Ruby, Lua, Perl, Python, Linux, C, C++, Tcl/Tk, Tomcat, PHP and MySQL. We're asked (and answer) many questions, and answers to those which are of general interest are published in this area of our site.

You can Add a comment or ranking to this page

© WELL HOUSE CONSULTANTS LTD., 2024: Well House Manor • 48 Spa Road • Melksham, Wiltshire • United Kingdom • SN12 7NY
PH: 01144 1225 708225 • FAX: 01144 1225 793803 • EMAIL: info@wellho.net • WEB: http://www.wellho.net • SKYPE: wellho

PAGE: http://www.wellho.net/solutions/perl-obj ... steps.html • PAGE BUILT: Wed Mar 28 07:47:11 2012 • BUILD SYSTEM: wizard