SoFunction
Updated on 2025-04-07

Perl5 OOP study notes page 1/2

After learning Perl's basic grammar, I have some experience in learning Perl's OOP. I don't know if there is any difference between the OOP versions of Perl, but I am learning Perl5, so I wrote the version number out in the title. Because I learned that there is a big difference between the OOP parts of PHP4 and PHP5, I have this concern.
When learning Perl's OOP, the two most important things are package and bless. As long as you figure out these two things, you will learn to be halfway through.
Perl's package
I feel that Perl's package is really similar to Java. Java's package is rooted with the directory in CLASSPATH, and defines and searches for hierarchical package names according to the directory. Perl is similar, using the directory in the @INC array as the root and searches for the hierarchical package name by directory. However, there is a little difference. Perl's package definition does not seem to need to correspond to the directory structure. I haven't studied the specific rules, because it is a good habit to define packages according to directory structure.
Compared to Java, Perl's package is a little interesting. Each layer of Java package corresponds to a directory, and finally a class file corresponds to the class name. Perl has been simplified, and the package directly references both the directory and file names. for example
In Java, the corresponding one is /name/jamesfancy/, and the source code is divided into two sentences to write.
Copy the codeThe code is as follows:

package ;
class MyClass {....}
package ;
class MyClass {....}

In Perl, name::jamesfancy::MyClass, which deals with /name/jamesfancy/. There is only one package in the source code to explain it.
Copy the codeThe code is as follows:

package name::jamesfancy::MyClass;
package name::jamesfancy::MyClass;

As for the content in the package, that is, variables and subroutines, as for the difference, I will talk about it later.
bless function
bless is a function used to bind a class to a reference type variable. It's strange why Perl uses this word, but it doesn't matter. We can imagine it as a little more vivid: just like the priest in the game adds a BUFF to someone through the blessing skill, bless binds a class to a variable of a reference type, and from then on this variable is blessed and has the variables and subroutines in this class.
The usage of bless is usually: bless ($ reference variable, class name);
Reference variables seem to be variables of any reference type. I have tried references from Scalar, Array and Hash and all succeeded. Outside of bless, this reference variable can be called an object. Of course, it is still a reference, a reference to the object.
One thing to note is that although this object has class variables and subroutines, we should regard the class variables and subroutines it has as static, in other words, as members of the class. At this point, the processing of subroutines is more special, but at least the variables of the class, that is, package variables, do not belong to the object. Therefore, all the data of the object is stored in the original data referenced by the object. Since everyone is used to the storage of object data in key-value pairs, usually, bless reference variables are references to Hash.
Very abstract? Give an example. If you don't know enough about OOP member functions, then just look at the content after the first sentence of each class's test function in the following example.
Copy the codeThe code is as follows:

#
package TestScalar;
sub test {
my $this = shift();
print("\nIn TestScalar::test()\n");
print("Scalar:\n ${$this}\n");
}

package TestArray;
sub test {
my $this = shift();
print("\nIn TestArray::test()\n");
print("Array:\n");
foreach my $item (@{$this}) {
print(" $item\n");
}
}

package TestHash;
sub test {
my $this = shift();
print("\nIn TestHash::test()\n");
print("Hash:\n");
while (my ($key, $value) = each %{$this}) {
printf(" %-4s = %s\n", $key, $value);
}
}

package main;

my $name = "James Fancy";
my $objScalar = \$name;
my $objArray = ['James', 'Fancy', 'Jenny'];
my $objHash = {'name' => 'James', 'age' => 30};

bless($objScalar, 'TestScalar');
bless($objArray, 'TestArray');
bless($objHash, 'TestHash');

$objScalar->test();
$objArray->test();
$objHash->test();

__END__

In TestScalar::test()
Scalar:
James Fancy

In TestArray::test()
Array:
James
Fancy
Jenny

In TestHash::test()
Hash:
name = James
age = 30

As can be seen from the above example, three types of references are converted into objects. The reason why classes are written as 3 instead of 1 is mainly to output different types of data in Test.

Member functions of classes and objects

Member functions are subroutines defined in package. There is no distinction between static and non-static functions, but I would rather everyone regard it as a static function, because although it can be called as a class member function or when it is called as an object member function, Perl secretly passes in an object reference. This also explains why the first sentence in a member function is usually

Copy the codeThe code is as follows:

my $this = shift();

Of course, $this is just a local variable, not a keyword, and you can also replace it with another name. For example, many people like to use $self, or $me, etc.
What would be the difference if a member function is called with classes and objects respectively? Let's take a look at another example:
Copy the codeThe code is as follows:

#
package MyClass;

sub test {
my ($this, @args) = @_;
print('-' x 40, "\n");
print("\$this is [$this], Ref of \$this is [", ref($this), "]\n");
print("Args: [@args]\n");
}

package main;

$obj = {};
bless($obj, 'MyClass');

MyClass->test("MyClass->test(...)");
$obj->test("\$obj->test(...)");

__END__
----------------------------------------
$this is [MyClass], Ref of $this is []
Args: [MyClass->test(...)]
----------------------------------------
$this is [MyClass=HASH(0x178a44)], Ref of $this is [MyClass]
Args: [$obj->test(...)]

From the results, we can see that no matter which method is called, the first parameter is secretly passed in by Perl. If it is a class call, the first parameter is the class. If it is an object call, the first parameter is the object. Therefore, you only need to compare the result of ref($this) with the class name to see which call it is. Therefore, a member function with better fault tolerance should first judge the first parameter passed in, for example
Copy the codeThe code is as follows:

sub foo {
my $this = shift();
return unless ($this ne 'MyClass');
# Other statements
}

There is another question here: Since the subroutines defined in packages are member functions, what is the difference between not a class package and not a class package? There is no difference in structure between them, the only difference is in processing. When calling a subroutine, Perl will not force a class or object to the front of the parameter list, but will do it when calling a member function, so the difference is differentiated according to your calling method.

It's okay to call the object members, $obj->foo() is fine, but when calling the class members, how do you know whether it is the called class member or the subroutine in the package? It depends on whether it is called through "->" or "::". The following examples can help understand:
Copy the codeThe code is as follows:

#
package MyClass;
use Data::Dumper;
sub test {
print('-' x 40, "\n");
print(Dumper(@_));
}

package main;

MyClass->test("MyClass->test(...)");
MyClass::test("MyClass::test(...)");

__END__
----------------------------------------
$VAR1 = 'MyClass';
$VAR2 = 'MyClass->test(...)';
----------------------------------------
$VAR1 = 'MyClass::test(...)';

Obviously, the subroutine called via "::" is not stuffed with Perl into a reference class parameter.

Constructor
Perl's OOP does not specify a special constructor, so you can treat any subroutine as a constructor, of course, what's important is what's in it. Since scripts are not usually written for oneself to read, we should name the constructor new according to everyone's habit. According to the custom of most OOP languages, new functions usually return an object or its reference or pointer. So in Perl, this new function needs to return an object reference. It is natural to include the bless action in the new function. Then a simple new function looks like this:
Copy the codeThe code is as follows:

sub new {
my $this = {};
bless($this);
}

This new function produces a Hash reference, bless it, and returns it. If you are wondering why you don't see the return statement here, then it is recommended that you check the information about the return value in the subroutine and check the description of the bless function. Let’s take a look at the complete program to understand how to use the new function.
12Next pageRead the full text