清新的Perl(九)——面向对象
对于一向标榜编程自由的Perl语言来说,面向对象的编程方式是不可缺少的。关于面向对象编程,我个人认为,讲解最好的是《Java编程思想(第四版)》。我学习编程语言,最先啃的一本书,便是它。说句实在话,当年啃书的方法不对,磕磕绊绊好多年才将它啃下来。而且,即便是啃下来了,还是不理解。直到后来,学完perl语言,开始进行Web开发,才真正的感悟到Java编程思想的精妙之处,可谓受益匪浅。
在这里,我相信读者均是为了学习perl而来,不推荐去生啃Java编程思想(万一都跑去学java就坏了)。对于任何一门编程语言来说,最重要的事情便是解决问题,无论是过程编程、还是面向对象编程,仅仅使用编程思想而已,没有对立和区别。当你实际进行开发时,很快会发现,一些问题用过程编程很简单,而一些问题用面向对象更简单。尤其是Perl语言,你会发现更加明显。
那么,何时我们会用到Perl的面向对象呢?实际上,很少,大部分问题用方法就能解决。即便你不看Perl各种教程、书籍中的面向对象一章的内容,丝毫不会影响你使用Perl解决问题。换句话讲,当你根据“清新的Perl”前八篇的要点看完一本Perl语言书籍、或者教程后,完全可以很好的做开发工作了。
现在回归正题,Perl语言的面向对象编程能解决什么问题?
这个问题,首先需要明白,想要学习Perl语言,用Perl语言解决的问题都是什么人?2020年了,我想基本上是像我一样的运维工程师、网络管理员了。
干运维这一行,xml、conf等一类的配置文件是经常要打交道的。Perl的正则表达式对于这类文件,是优秀的利器。比方说,VPN、防火墙、上网行为等设备,常常可以导入、导出xml配置文件。我们可以用Perl写一个脚本,去操作xml配置文件,增加、删除配置。
操作XML文件,我们需要从MetaCPAN上找第三方模块。例如XML::LibXML,这是一个面向过程的Perl模块,当你查看文档会发现,这个模块很复杂,包含的子模块繁多。但是这个模块可以完整的解析一个无论多复杂、多庞大的XML文件。
现在我们可以使用XML::LibXML模块,定制一个适合于我们设备配置文件的程序,辅佐我们方便地进行设备配置任务。当我们写完后,会发现这个程序很复杂,很啰嗦,同样也很难移植给其他场景使用。
假设,我们已经写好了一个配置防火墙ACL的XML文件。在使用一段时间后,我们发现有三个工作场景:
一,要从XML里面删除一些IP地址,同时要增加一些IP地址;二,仅仅从XML里面增加一些IP地址;三,仅仅从XML里面删除一些IP地址。
当我们只学过过程编程,而没有接触面向对象编程时,我们会有这样的思路:分为两个方法,一个方法负责删除、一个方法负责增加。这两个方法里面会有大量重复的代码,例如初始化XML::LibXML模块的代码、打开和写入XML文件代码等等。而且,这些重复的代码意味着计算机重复的工作——比如,每个方法内都要打开、再关闭保存一次文件。明明我们操作的是同一个XML,可为什么要每次都要先打开文件再进行增加或删除操作呢?
我们能否把这个文件看成一个对象,无论做多少次增加、删除IP地址的操作,我们都只打开、关闭保存一次文件呢?可以,这就是面向对象的编程方式。
我们将这个XML文件作为一个对象,把删除、增加两个方法关联到这个对象上,保证我们无论调用多少次删除、增加操作,都仅仅是在同一个XML文件对象上进行的。
下面,我们就可以简单写一个Perl的类了。
package Hello;
use strict;
use warnings;
use utf8;
#构造器
sub new {
my $class = shift;
# load
my $doc = "Perl";
my $self = {};
$self->{doc} = $doc;
bless $self,$class;
return $self;
}
sub hello {
my $self = shift;
my $doc = $self->{doc};
print "Hello World,$doc\n"; #窗口显示“Hello World,Perl”
}
1;
如上所示,Perl的类,和模块写法基本是一样的。区别在new中,new方法的目的在于创建一个对象,new方法关键的语句包括了:
#这一步创建一个类
my $class = shift;
#这一步创建一个对象——哈希(散列),类似上面的代码,可以将需要所有方法操作的变量保
#存在$self里面,比如说一个文件变量、XML变量等等
my $self = {};
#将哈希和类关联起来
bless $class,$self;
#返回对象
return $self;
在这一步里面,我们最主要的操作是得到一个对象,也就是$self散列,以及通过bless把类和$self关联起来,是$self真正的成为一个类的对象实例。
如何将方法和对象关联起来呢?我们仅需要记住每一个方法传输的第一个参数是$self:
my $self = shift; #放置于方法的第一行
以上,便是Perl语言的面向对象编程的主要内容。