1 Object-oriented programming in Perl

In the following example, a package (or class) Student is defined. It contains three methods: new(), printDetails() and enroll(). The method new() is used as a constructor to instantiate new objects. But it is just a convention to use the word "new", any other word could be used instead. The objects of the class Student have two attributes: name and courses. These are numbered $_[1] and $_[2] in the subroutine because the name of the package itself is stored in $_[0].

#!/usr/local/bin/perl
#########################################
package Student;
sub new {
      my $self = {};
      bless $self;
      $self->{name} = $_[1];
      $self->{courses} = $_[2];
      return $self;
}
sub printDetails {
      my $self = $_[0];
      print "Name: $self->{name}\n";
      print "Courses: @{$self->{courses}}\n";
}
sub enroll {
      my $self = $_[0];
      my $course = $_[1];
      push (@{$self->{courses}},$course);
}
#########################################
package main;
my($student1) = new Student("Fred", ["L548"]);

print "Input the courses which $student1->{name} is enrolled in.\n";
print "When finished, type X.\n";
$newcourse = <STDIN>;
chomp $newcourse;

while ($newcourse !~ /x/i) {
$student1->enroll($newcourse);
$newcourse = <STDIN>;
chomp $newcourse;
}

$student1->printDetails();

1.2 Exercises

1) Add further attributes to the student class (phone number, email address, degree, etc).

2) Create an array of students. Let users add new students to the array. Ask the user for the name of a student and then print his/her details.

3) Create a method creditHours that computes the number of credit hours for a student assuming that every class is a three credit class.

4) Create a class Employee that contains information about names, ages and positions. What could be useful methods for the class?

1.2 Blessing of $self

Without blessing the variable in the subroutine "new", a different notation would have to be used:
Student::printDetails($student1);
instead of
$student1->printDetails();
Using that notation any subroutine from any package can be included in a script. A blessed variable contains an internal pointer to its package, i.e. the variable becomes an "object" of that class.

1.3 Optional Materials: Pointers (References)

The following examples provide more details for the notation (implementation) of object-oriented programming in Perl. Object-oriented notation was added to Perl in version 5. Therefore existing constructs (such as pointers and hashs) were used for the object-oriented features.

#!/usr/local/bin/perl

# normal hash
%hash = ("name", "Fred", "color", "white");
print "$hash{name}\n";
print "$hash{color}\n";

# pointer to a hash
$pointer_to_hash = \%hash;
print "$pointer_to_hash->{name}\n";
print "$pointer_to_hash->{color}\n";

The subroutine "new" returns a pointer to a hash. The hash is defined as "$self = {...}" instead of as "%self =(...)". "$self" is a scalar and therefore a pointer to a hash.

#!/usr/local/bin/perl

sub new {
my $self = {};
$self->{'name'} = $_[0];
$self->{'color'} = $_[1];
return $self;
}

my($cat) = new("Fred","white");
print "$cat->{name}\n";
print "$cat->{color}\n";

1.4 Another example

#!/usr/local/bin/perl

package Cat;
sub new {
my $class = $_[0];
my $self = {};
bless $self;
$self->{'name'} = $_[1];
$self->{'color'} = $_[2];
return $self;
}
sub meow {
print "meow\n";
}
sub printDetails {
my $self = $_[0];
print "$self->{name}\n";
print "$self->{color}\n";
}
###################################

package main;
my($cat) = new Cat("Fred", "white");
$cat->meow();
$cat->printDetails();

1.5 Exercise

5) In analogy to the example above, create a package (class) for another type of pet besides cat or dog (see below).

1.6 Encapsulation, inheritance, and polymorphism

#!/usr/local/bin/perl
package Animal;
sub printDetails {
my $self = $_[0];
print "$self->{name}\n";
print "$self->{color}\n";
}
###################################
package Cat;
@ISA = qw(Animal);
sub new {
my $class = $_[0];
my $self = {};
bless $self;
$self->{'name'} = $_[1];
$self->{'color'} = $_[2];
return $self;
}
sub speak {
print "meow\n";
}
###################################
package Dog;
@ISA = qw(Animal);
sub new {
my $class = $_[0];
my $self = {};
bless $self;
$self->{'name'} = $_[1];
$self->{'color'} = $_[2];
return $self;
}
sub speak {
print "woof\n";
}
###################################
package main;
my($cat) = new Cat("Fred", "white");
my($dog) = new Dog("Max", "black");
@pets = ($cat,$dog);

foreach $pet (@pets){
$pet->speak();
$pet->printDetails();
}

1.7 Exercise

6) Add your pet from the previous exercise to the Animal package.

1.8 Modules

A module is a package stored in a file by itself and named "packagename.pm". The last executed line in a module should be "return 1;". A package can be used in a different file by including "use packagename;" at the beginning of the file.

1.9 Exercise

7) Save Animal, Cat, Dog and the additional pet as modules by themselves. To use them you can either include "use" statements for all four of them in the main file or you use Cat, Dog and the other pet in the main file and Animal in Cat, Dog and the other pet. Try both possibilities.