1. Perl
  2. Object Oriented
  3. Introduction

Introduction to Object Oriented

Many people find it difficult to do object-oriented programming in Perl, and don't intuitively know how to create classes or define instance variable.

In fact, with the help of modules, Perl's object orientation is very straightforward. This time, I will explain Perl's object orientation using a module called Object::Simple.

Install Object::Simple

Install Object::Simple. You can easily install modules using cpan.

cpan Object::Simple

Now you are ready to go.

Class definition

In Perl, classes are defined using package . First, use the -base flag to create a class that inherits from Object::Simple. Remember the following description as a spell first.

package MyClass;
use Object::Simple -base;

Constructor

This way you can define a class called MyClass . You can create an object from a class using the constructor new . (This new is inherited from Object::Simple.)

my $obj = MyClass->new;

The new method can receive a hash or a hash reference.

my $obj = MyClass->new(foo => 1, bar => 2);
my $obj = MyClass->new({foo => 1, bar => 2});

This is set as an attribute value.

Accessor

Next, let's define an accessor. An accessor is a method for accessing an attribute value (instance variable). You can access the attribute values by defining an accessor.

Use the has function to generate an accessor.

has'foo';

You can access the attribute values by defining an accessor.

# Value setting
$obj->foo(1);

# Get value
my $foo = $obj->foo;

You can also specify defaults for attribute values.

has foo => 1;

When the accessor is first called if the attribute value is not set

The default value is set to the attribute value.

# Get the default value of 1
my $default = $obj->foo;

If you want to specify a reference or object as the default value, it must be the return value of the subroutine reference.

has foo => sub {[]};
has foo => sub {{}};
has foo => sub {MyClass->new};

You can also generate multiple accessors at once.

has [qw/foo bar baz /];
has [qw/foo bar baz /] => 0;

Inheritance

Use -base for inheritance. Let's create a SubClass that inherits from MyClass .

package MyClass;
use Object::Simple -base;
package SubClass;
use MyClass -base;

Superclass method call

You can use SUPER to call superclass methods.

package SubClass;
use MyClass -base;

sub clear {
  my $self = shift;
  
  $self->SUPER::clear;
}

Constructor override

You may want to override the constructor in a subclass. To override the constructor:

package MyClass;
use Object::Simple -base;

sub new {
  my $class = shift;
  
  my $self = $class->SUPER::new(@_);
  
  return $self;
}

Since new is a constructor, be sure to return the object itself.

Creating a class - Practice

Oh mysteriously, Perl's object-oriented programming is almost master if you remember this much. Then, it is a practical edition. Let's create a Point class and a Point3D class.

Point class

  • Point is a class that represents a point.
  • It has accessors x and y.
  • It has a method called clear that clears the values of x and y to 0.
package Point;
use Object::Simple -base;

has x => 0;
has y => 0;

sub clear {
  my $self = shift;
  
  $self->x(0);
  $self->y(0);
}

1;

(The "1;" at the end is due to the rule that the file that writes the module must end with true.)

The Point class can be used as follows.

use Point;
my $point = Point->new(x => 3, y => 5);
print $point->x;
$point->y(9);
$point->clear;

Point3D class

  • Point3D is a class that represents a three-dimensional point.
  • It has accessors x, y, z.
  • It has a method called clear that clears the values of x, y, z to 0.

Point3D is created by inheriting Point . The clear method has been overridden to clear the values of x , y and z .

package Point3D;
use Point -base;

has z => 0;

sub clear {
  my $self = shift;
  
  $self->SUPER::clear;
  
  $self->z(0);
}

1;

The Point3D class can be used as follows.

use Point3D;
my $point = Point->new(x => 3, y => 5, z => 8);
print $point->z;
$point->z(9);
$point->clear;

Executable example

I'll write an example that can be executed.

lib/Point.pm

Create a directory called lib and create a file called Point.pm in it.

package Point;
use Object::Simple -base;

has x => 0;
has y => 0;

sub clear {
  my $self = shift;
  
  $self->x(0);
  $self->y(0);
}

1;

lib/Point3D.pm

Create a file called Point3D.pm in a directory called lib.

package Point3D;
use Point -base;

has z => 0;

sub clear {
  my $self = shift;
  
  $self->SUPER::clear;
  
  $self->z(0);
}

1;

test.pl

This is an example to read and use the class. You can add a module search path by using the lib module.

use strict;
use warnings;
use lib 'lib';
use Point3D;

my $point = Point3D->new(x => 3, y => 5, z => 8);

# 8 is displayed
print $point->z . "\n";

$point->z(9);

# 9 is displayed
print $point->z . "\n";
$point->clear;

# 0 is displayed
print $point->z . "\n";

Script execution

The directory structure is as follows.

test.pl
lib - Point.pm
    - Point3D.pm

Please execute as follows.

perl test.pl

Object - oriented programming concept

Inheritance

To better understand Object::Simple, I would like to explain object-oriented concepts.

The first object-oriented concept is "inheritance". "Inheritance" means "if class Q inherits from class P, then class Q can call all the methods of class P".

+ - - +
| P | Superclass
+ - - + Define method1 and method2
  |
+ - - +
| Q | Subclass
+ - - + Define method3

Since class Q inherits from class P, class Q can call all the methods of class P in addition to the methods of class Q. In other words, class Q can call method1, method2 and method3.

package P;
use Object::Simple -base;

sub method1 {...}
sub method2 {...}
package Q;
use P -base;

sub method3 {...}

Perl has useful functions and methods to help with object-oriented programming. To find out which class an object belongs to, use the ref function.

my $class = ref $obj;

To find out if an object inherits a particular class, use the isa method.

$obj->isa('MyClass');

Use the can method to find out if an object (or class) can call a particular method.

MyClass->can('method1');
$obj->can('method1');

Encapsulation

The second concept of object-oriented programming is encapsulation. "Encapsulation" means "no direct access to data internally". You must use the published methods described in the documentation. By following this rule, everything will be simple.

In order to follow this rule, it is necessary to generate an accessor to get and set the value.

my $value = $obj->foo;
$obj->foo(1);
Accessing data directly is a bad habit.
# Not good
my $value = $obj->{foo};
$obj->{foo} = 1;

Polymorphism

The third concept of object-oriented programming is "polymorphism".

"Polymorphism" becomes two concepts of "overload" and "override"

It will be split.

Perl programmers don't have to worry about overloading. Perl is a dynamic language, so subroutine can accept any value. Overloading is required for languages with static types such as C ++ and Java.

"Override" means "in a subclass, you can change the methods of the base class".

package P;
use Object::Simple -base;

sub method1 {return 1}
package Q;
use P -base;

sub method1 {return 2}

Method1 of class P returns a value of 1. Method1 of class Q returns a value of 2. In other words, in class Q, method1 has been overridden.

# Returns 1
my $obj_p = P->new;
$obj_p->method1;

# Returns 2
my $obj_q = Q->new;
$obj_q->method1; # Return value is 2

If you want to call a method of the base class from a subclass, use the SUPER pseudo-class.

package Q;
use Object::Simple -base;

sub method1 {
  my $self = shift;
  
  # Call method1 of P using the SUPER pseudo-class
  my $value = $self->SUPER::method1 (@_);
  
  return 2 + $value;
}

new can be overridden. For example, if you want to initialize the object, override new.

sub new {
  my $self = shift->SUPER::new(@_);
  
  # Initialization process
  
  return $self;
}

If you want to change the argument of new, you can solve it by overriding new.

sub new {
  my $self = shift;
  
  $self->SUPER::new(x => $_[0], y => $_[1]);
  
  return $self;
}

Understanding these three concepts, "inheritance, " "encapsulation, " and "polymorphism, " will create a powerful enough object-oriented program and make the source code readable by users in other languages.

Package block syntax

In Perl 5.14, a package block syntax has been added that allows you to write the following, eliminating the need to write a "1;" at the end of the file. If you are using Perl 5.14 or higher, you may want to try it.

package Point {
  use Object::Simple -base;

  has x => 0;
  has y => 0;

  sub clear {
    my $self = shift;
    
    $self->x(0);
    $self->y(0);
  }
}

Summary

Perl is a flexible language. You can be completely object-oriented in the language Perl. Perl's object-orientation is sometimes ridiculed as a retrofit implementation, but it's functionally object-oriented and complete.

Perl has a namespace and is object-oriented, so it can withstand large-scale development. As the scale grows, I think it's a good idea to program in an object-oriented way.

Related Informatrion