Broad Network


Protected Attributes and Methods in Perl OOP

Perl Object Oriented Programming – Part 6

Perl Course

Foreword: In this part of the series, I talk about protected visibility of attributes and methods for a Perl class and corresponding object.

By: Chrysanthus Date Published: 26 Sep 2015

Introduction

This is part 6 of my series, Perl Object Oriented Programming. In this part of the series, I talk about protected visibility of attributes and methods for a Perl class and corresponding object. Protected visibility refers to the ability of an inherited class and corresponding object, to access the private members of the parent class. An attribute or method can be called a member of the class and corresponding object. If an attribute or method can be accessed inside its class and object, as well as inside the derived class (and object), then that member is a protected member to the subclass. Subclass, inherited class and derived class mean the same thing. You should have read the previous parts of the series before reaching here, as this is a continuation.

Code Example
Read and try the following code:

use strict;

    {package TheCla;

        my %ha = (wordA => "pencil", wordB => "ruler");
        $ha{coderef} = sub
                    {
                        print "I have a $ha{wordA} and a $ha{wordB}", "\n";
                    };

        sub getParent
            {
                return undef unless ((ref($_[0]) eq "TheSub")||($_[0] eq "TheSub"));
                return $ha{$_[1]};
            }
        sub setParent
            {
                return undef unless ((ref($_[0]) eq "TheSub")||($_[0] eq "TheSub"));
                return undef if ref($ha{$_[1]}) eq "CODE";
                $ha{$_[1]} = $_[2];
                return $ha{$_[1]};
            }

        sub meth
            {
                &{$ha{coderef}}();
            }


        sub new
            {
                bless {word1 =>"pen", word2=>"book"}, $_[0];
            }
    }

    {package TheSub;
        
        @TheSub::ISA = ("TheCla");

        sub childMeth
            {
                print TheSub->getParent("wordB"), "\n";
            }
    }

You should not have any output. The goal in this tutorial is to enable the subclass access the private members of the parent class. The private members should still not be accessible in the main program. Remember, all private members are in the my hash.

The parent class here is similar to the parent class of the previous part of the series, but it has two new methods, which are needed to make the private members protected, that is, accessible to the inherited class (and corresponding object). The subclass description is the same as one of the subclass description in the previous part of the series, but just has a different name.

We now look at the two new methods in the parent class. When a class is inherited, all the functions are inherited. Attributes are not inherited, unless they are hard coded initialization. So, the two functions, getParent() and  setParent are inherited, and can be accessed by the subclass (in the derived class description or by the derived class’ object).

The aim of getParent() is for the subclass or its object, to read the value of a parent private member. The aim of setParent() is for the subclass or its object to change the value of a parent private attribute. The method cannot change the reference (code reference) of a private method, because of the way it has been coded.

The getParent Method is:

        sub getParent
            {
                return undef unless ((ref($_[0]) eq "TheSub")||($_[0] eq "TheSub"));
                return $ha{$_[1]};
            }

The aim of this method is to read the value of a private attribute. For private method, it reads the code reference, which then has to be dereferenced, in order to call the function (method). The first line in the method definition is a simple statement. This will return undef unless the first argument to the method is the subclass’ object reference or the subclass name. Remember that the first argument of a function inside a class is a class name or the reference to an object. The predefined function, ref() converts an object’s reference to the class’ name. If this first statement is executed, then any line below it, within the method body, will not be executed, because this statement is a return statement. The second statement returns the value of the private attribute.

As you can see from the first statement, this method can only be evaluated by the subclass or its object. It will return undef, if called by a different package, even the parent package.

The setParent() method is:

        sub setParent
         {
                return undef unless ((ref($_[0]) eq "TheSub")||($_[0] eq "TheSub"));
                return undef if ref($ha{$_[1]}) eq "CODE";
                $ha{$_[1]} = $_[2];
                return $ha{$_[1]};
         }

The aim of this method is to change the value of a private attribute of the parent class and to return the new value. This method should not change any code reference of a private method.

The first statement in the method definition will return undef unless the value of its first argument is a reference to the subclass or it is the name of the subclass. If this statement is executed, no other statement below it in the function definition will be executed, because it is a return statement. The next statement in the method will return if the private member is a method (code reference function).

If the first two statements are not executed, then the third statement changes (sets) the value of the private attribute. The last statement returns the new value.

It is these two methods that make the private attributes and methods protected for the subclass; that is, the private attributes and methods cannot be accessed outside the parent class, but can be accessed by the subclass.

For the rest of the tutorial, I will talk about the access of the private members outside the parent class, in the main program and in the subclass. In this tutorial, the private members are also the protected members. The private members have been made protected, by the operation of the above two functions.

Access in Main Program
Add the following code to the bottom of the above code; try the complete code and note that the private attributes cannot be accessed from the main program, using the parent class name and the getParent() method:

    print TheCla::getParent("wordA");

Replace the added code with the following and note that the private method cannot be accessed from the main program, using the parent class name and the getParent() method (you may get an error message):

    &{TheCla->getParent("coderef")}();

The expression, TheCla->getParent("coderef") should return the code reference. &{}() dereferences the method reference, and so, calling the function.

Replace the added code with the following and note that the private attributes cannot be accessed from the main program, using a parent object and the getParent() method:

    my $obj = TheCla->new();
    print $obj->getParent("wordA");

Replace the added code with the following and note that the private method cannot be accessed from the main program, using a parent object and the getParent() method (you may get an error message – you may also have to catch the undef value):

    my $obj = TheCla->new();
    &{$obj->getParent("coderef")}();

The expression, $obj->getParent("coderef") should return the code reference. &{}() dereferences the method reference, and so, calling the function.

The setParent() method, called in a similar way, will also not achieve anything.

Accessing with the subclass
Replace the added code above, with the following; try the complete code and note that the private attributes can be accessed from within and outside the subclass, using the subclass name and the getParent() method:

    TheSub->childMeth(), "\n";
    print TheSub->getParent("wordB"), "\n";

Replace the added code above, with the following; try the complete code and note that the private attributes can be changed from outside the subclass, using the subclass name and the setParent() method:

    TheSub->setParent("wordB", "ink");
    print TheSub->getParent("wordB");

The setPearent function takes two arguments: the first is the key of the hash in quotes and the second is the value of the hash in quotes (except for numbers).

Replace the added code with the following and note that the private method can be accessed from outside (and even within) subclass, using the subclass name and the getParent() method:

    &{TheSub->getParent("coderef")}();

The expression, TheCla->getParent("coderef") should return the code reference. &{}() dereferences the method reference, and so, calling the function.

Replace the added code with the following and note that the private attributes can be accessed from outside (and even within), using a subclass object and the getParent() method:

    my $childObj = TheSub->new();
    print $childObj->getParent("wordA");

Replace the added code with the following and note that the private method can be accessed (and even within) using a subclass object and the getParent() method:

    my $childObj = TheSub->new();
    &{$childObj->getParent("coderef")}();

The expression, $childObj->getParent("coderef") should return the code reference. &{}() dereferences the method reference, and so, calling the function.

The setParent() method, called in a similar way, will also be effective.

Before we leave this part of the series, know that getParent() and setParent() are public methods, but they decide which package will access the private members.

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

BACK NEXT

Comments

Become the Writer's Fan
Send the Writer a Message