Broad Network


Perl OOP Basics

Perl Object Oriented Programming – Part 1

Perl Course

Foreword: In this part of the series, I give you the basics of what is known as Perl Object Oriented Programming.

By: Chrysanthus Date Published: 26 Sep 2015

Introduction

This is part 1 of my series, Perl Object Oriented Programming. In this part of the series, I give you the basics of what is known as Perl Object Oriented Programming, which is abbreviated as Perl OOP.

Pre-Knowledge
This series is part of the volume, Perl Course. At the bottom of this page, you will find different series you should have read before coming here, in order to understand this one.

Preamble
When you have a set of variables and functions (subroutines) that work together and would appear in many parts of your code, you can put all that in one generalized unit, called a class. There will be no need for repeat typing of the set. In this tutorial, I am referring to any set of variables and functions. The set of variables and functions form a class, if brought together in a special way. The functions work with the values of the variables. Under that condition, it is possible that the values of the variables and the results of the accompanying functions can be changing. In order to use the class after it has been defined, you have to create a corresponding unit from the class, everything being equal. That particular unit created is called an object. In this part of the series, I give you the basic explanation of Perl classes and their objects.

You should read this series in the order given; that is, you begin with part 1, then part 2, and so on.

Recall
Remember, in Perl, when a function (method) is called, it receives its arguments in the @_ array, which is available implicitly as soon as the function begins execution. The values in this array can be accessed by $_[0], $_[1], $_[2], etc.

Group of Variables and Functions
Let us consider a group of variables and functions that would work as a generalized unit. Read and try the following code and note that it returns the sum of 2 and 3.

use strict;

    my $num1 = 2;
    my $num2 = 3;

    sub add
        {
            my $sum = $_[0] + $_[1];
            return $sum;
        }

    my $result = add($num1, $num2);

    print $result;

In the code you have two variables ($num1 and $num2) and a function (add). In the code, the function is called, and the returned sum is held in the new variable, result. The result is sent to the output (printed at the console).

Now, the above code sums two particular numbers, which are 2 and 3. You would want a piece of code that sums any two numbers, not just 2 and 3. One possibility is to include another function that would receive the two numbers, change the values of the two variables, then call the add($no1, $no2) function. There is another possibility, which has become very popular over the years; it is to create a class, then create an object from the class that would add two particular numbers.  A class is a generalized unit of code, from which things call objects can be created to do particular tasks. An object is called the Instance of the class. Note: in the above code the two variables ($num1 and $num2) and the function (add()), work together. So, it is advisable to have the two variables and the function in one unit called a class.

Class
A class is a generalized unit (definition) from which objects can be instantiated (created). A class is basically a code unit that has variables and functions that work together. The variables are called Attributes and the functions are called Methods. A class can solve a problem (carry out a task), but it is generally not advisable for a class to solve the problem. It is an object created from the class that is expected to carry out a task (solve a problem), not the class.

When you create an object from a class, we say you instantiate the class. A variable of the class is called an attribute of the class. A function of the class is called a method of the class. An object created from a class has the same attributes and methods as the class.

A Class and Object created from the above Code
The above code can be converted into a class and object as follows:

use strict;

    {package Calculator;

        sub new
            {
                bless {}, $_[0];
            }

        sub add
            {
                my $ref = $_[0];
                my $sum = $ref->{'num1'} + $ref->{'num2'};
                return $sum;
            }

    }

    my $obj = Calculator->new();
    $obj->{'num1'} = 2;
    $obj->{'num2'} = 3;

    my $result = $obj->add();
    print $result;

You define a class beginning with the reserved word, package, at the beginning, inside a pair of curly brackets. This is followed by the name of the class. A class is a package. You choose whatever name you want for the class. I have given the name Calculator, because the class is doing some calculation. There are statements and blocks inside the curly brackets. All the statements and blocks for the class go inside the braces. It is conventional to type the variables, which are the attributes, first before the functions, which are the methods. However, in Perl, these variables and their possible assigned values should be in a hash. The variables in the hash are the attributes and the functions in the class (not in the hash) are the methods. The variables and the function we had in the previous program are the same variables and function we now have in the class and object, typed in, from a different perspective. The blessed hash is the object – see below.

In the above code, the hash is empty. The hash is anonymous and it is coded in the user defined function, new(). This hash (of curly brackets) returns a new reference each time the function, new() is called. It is given its key/value pairs (attributes) later. These key/value pairs are the variables and their assigned values. In Perl, you need a reference in order to have (instantiate) an object from a class. That is why the hash has been defined in that form.

The function (subroutine) called, new, in the class (description) has a special purpose. It should always be in the class description (definition). It is called the constructor method or constructor function. You can give it whatever name you want, but, new, is very appropriate. The minimum you should have in the constructor function is what I have given above. In Perl, the last statement in a function returns its value. The bless statement returns the reference of the hash.

The purpose of the constructor function, new, is to instantiate (create) an object from the class. In order to instantiate an object, a reference to the hash is needed. The statement in the function constructor uses the Perl predefined function, bless(). The purpose of this function is to make the hash the object by linking the hash to the functions of the package (class). The function has two arguments. The first argument is an anonymous hash. The second is the name of the class (package) as a string (in quotes). Now, when a function inside a package is called, the first argument of the function is the name of the package (class). That is why you have $_[0] above, as the second argument to the bless function.

The bless function returns the reference to the hash. And so the constructor function returns this same reference. The last statement of a Perl function (method or subroutine) returns its result, whether it has the return instruction or not. The last statement of the constructor method should be the bless statement.

The difference between a blessed hash and an ordinary hash is, that a blessed hash can call the functions of the package, passing its reference as the first argument to each of the functions when called. An ordinary hash is not linked to any function and so cannot pass its reference to any function.

Next, in the class description you have the definition of the method, add(). I will explain the use of the first statement later. The second statement in this function (method) adds the value of the key, num2 to the value of the key, num1. These keys are of the anonymous hash in the constructor function. The reference to the hash is held by $ref. Note the use of $ref, num1 and num2 with -> in the statement. The add() method returns the sum.

After the class description above, you have the following statement that instantiates the object.

    my $obj = Calculator->new();

This statement is outside (and below) the class description. The expression on the right of the assignment operator has the class name, Calculator. This is followed by the arrow operator (->); and then the constructor method, new(). Here, this method does not take any argument. However, since it is preceded by the class name, the first argument that the called method will receive is the class name (Calculator). The called constructor method has not used the class name in its definition (body) directly, because it has used $_[0], which has the class name as a string. If $_[0] is omitted from the bless function, the class name will still be assumed. The expression on the right of the assignment operator here, returns a reference. This reference is the reference of the anonymous hash, returned by the bless() function, which is, in this case, now, returned by the constructor function, new(). So, $obj is holding the reference to the blessed hash, which is the created object. In Perl, you can omit the parentheses of a function call. So instead of, new(), you can have, new.

The next two statements in the code are:

    $obj->{'num1'} = 2;
    $obj->{'num2'} = 3;

The object is now a region in memory, pointed to by $obj. The class is different. The class is code surrounded by curly brackets, where the first word in the braces is the reserved word, package. When an object is instantiated (created), it has the properties and methods of the class. These two statements give values to new keys of the hash in the object, and not in the class.

The next statement calls the add method of the object, which adds the values of the keys of the hash in the object. Note how the add method has been called, using the object, $obj and the arrow operator. This particular method has not taken ordinary arguments. However, as the function is called, the first argument to the function (method) is the reference to the object, held by $obj. That is why, in the function definition, the first statement assigns the value in $_[0] to $ref. The value in $_[0] is the reference to the hash, which has been blessed (now the object). The method returns the result of the addition. Remember, to access the element of a hash, given its reference, you begin with the reference, followed by the arrow operator, and then curly brackets having the key of the element.

The last statement in the code sends the result (sum) to the output.

Note, the key/value pairs are the attributes of the instantiated object. Different instantiated objects from a class have the same key names but different values. In the above situation, the class description has no key/value pairs; in this case, you can say it has would-be key/value pairs; key/value pairs which will actually be seen in objects.

Using the Object Reference in a Method
In the above code, you have the method,

        sub add
            {
                my $ref = $_[0];
                my $sum = $ref->{'num1'} + $ref->{'num2'};
                return $sum;
            }
Whenever the method of an object is called, the first argument sent to the method is the reference of the object. That is why the first statement in this method assigns the reference of the object to a variable. The variable, which now holds the object reference, can be used through out the method definition (body). Each object has its own hash and to access a property of the hash you need the reference of the hash, which is the reference of the object. In this way, even though a method belongs to a class, when called, it acts on a particular object.

Do not confuse between the method call of a class and the method call of an object. When the method call is of a class, the first argument received in the method definition (body) is the name of the class. When the method call is of an object, the first argument received is the reference of the object. In the above script, the new() method call is of the class and the add() method call is of an object.

More than One Object from a Class
Yes, after defining a class you can create many objects from it. In the following code, two objects are instantiated from one class. The two objects have the same attributes but with different attribute values. That is, the two objects have the same keys, but with different key values. So, the results from the different objects are different.

use strict;

    {package Calculator;

        sub new
            {
                bless {};
            }

        sub add
            {
                my $ref = $_[0];
                my $sum = $ref->{'num1'} + $ref->{'num2'};
                return $sum;
            }

    }

    my $obj1 = Calculator->new();
    my $obj2 = Calculator->new();

    $obj1->{'num1'} = 2;
    $obj1->{'num2'} = 3;

    my $result1 = $obj1->add();
    print $result1, "\n";

    $obj2->{'num1'} = 6;
    $obj2->{'num2'} = 7;

    my $result2 = $obj2->add();
    print $result2, "\n";

Try the code, if you have not already done so.

Attributes after Instantiation
In Perl OOP the attributes (key/value pairs) are normally given after instantiation of the object, as in one of the code segments above, retyped here:

    my $obj = Calculator->new(); #instantiation
    $obj->{'num1'} = 2;
    $obj->{'num2'} = 3;

Object Methods with Arguments
The add() method above does not have typed arguments. Nothing stops you from having typed arguments in your method. In this case the calling method should use the arguments. Now, you must remember this about the arguments of object methods: For any method of an object, e.g. $obj above, the first argument received by the called method is the reference to the object (e.g. $obj) and it is not typed as an argument in the calling method. In the above code, each time the constructor function, new(), is called, a new anonymous hash is created and the reference to the hash is returned by the constructor function. The bless operator (within new()) makes the hash an object for the class.  It is this reference that is still returned by the calling new() method, to be value of the instantiated object identifier ($obj).

The following script illustrates the use of arguments in a method. The reference (code) of the instantiated object is first printed out. Read and try the script:

use strict;

    {package Calculator;

        sub new
            {
                bless {};
            }

        sub mthd
            {
                print $_[0]."\n";
                print $_[1]."\n";
                print $_[2];
            }

    }

    my $obj = Calculator->new();
    $obj->mthd("one", "two");

The method first prints out the reference (code), then the string, one and the string, two. For the printed object reference you will see something like,

    Calculator=HASH(0x3f3d9c)

Note again: for the constructor method (new), the first argument (not typed) is the name of the class and not the reference to the object. At the end of the constructor method evaluation, a new anonymous object (hash) is created; its reference is returned. On the other hand the first argument (not typed) of an object method is the reference to the object and not the name of the class.

Summary
A class is a code unit consisting of attributes and methods. An object has the same attributes and methods as the class (everything being equal). The main difference between a class and an object is that, for a class the attributes do not normally have values, while the attributes for an object have values. You create an object from a class. Creating an object is instantiating the object. There can be many objects to one class. Objects differ from one another in the values their attributes have.

Perl OOP differ from conventional OOP in the sense that, with Perl OOP, the attributes and their values are normally given after instantiation, instead of giving attributes without values to the class description; also different objects in Perl for the same class, can have different attribute/value pairs.

That is it for this part of the series. We stop here and continue in the next part.

Chrys

Related Links

Perl Basics
Perl Data Types
Perl Syntax
Perl References Optimized
Handling Files and Directories in Perl
Perl Function
Perl Package
Perl Object Oriented Programming
Perl Regular Expressions
Perl Operators
Perl Core Number Basics and Testing
Commonly Used Perl Predefined Functions
Line Oriented Operator and Here-doc
Handling Strings in Perl
Using Perl Arrays
Using Perl Hashes
Perl Multi-Dimensional Array
Date and Time in Perl
Perl Scoping
Namespace in Perl
Perl Eval Function
Writing a Perl Command Line Tool
Perl Insecurities and Prevention
Sending Email with Perl
Advanced Course
Miscellaneous Features in Perl
Perl Two-Dimensional Structures
Advanced Perl Regular Expressions
Designing and Using a Perl Module
More Related Links
Perl Mailsend
PurePerl MySQL API
Perl Course - Professional and Advanced
Major in Website Design
Web Development Course
Producing a Pure Perl Library
MySQL Course

NEXT

Comments

Become the Writer's Fan
Send the Writer a Message