在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
缘由 最近反过头来看Perl,一方面是我的客户厂家用Perl开发了很多东西,另一方面在了解过程中,又复习了Perl语言,并且有了一些心得。记录下来,供大家参考。 我在做一个小程序,就是解析一个文本文件,将其中的内容进行处理,并保存在另一个文件。 背景知识
1. Perl的对象化编程实现 请参考阅读: O'Reilly - Advanced Perl Programming.pdf - 第7章 [Object-Oriented Programming] 2. 在Perl中如何使用引用 http://www.chinaunix.net/jh/25/504623.html 3. Perl中如何读取文件 Perl cookbook [O'reilly Perl Cookbook.pdf] - 第7章 [File Access] 4. Perl的正则表达式 http://www.chinaunix.net/jh/25/159388.html 具体实现
对象编程是为了解决长期依赖困扰的维护和扩展的工作。如果我们的代码只写一次,以后再也不需要改动,那么也许现代编程模型就不会演化。当然我们知道这是不可能的。世界唯一不变就是变化。 Perl做为一种功能强大的脚本语言在各个方面都有运用(但没有在UI方面使用),但是由于脚本语言的特性,write once的标签一直伴随着它。大家普遍认为它是一种晦涩的并难以维护的程序语言。 其实这方面,大家有一些误解。语言使用跟开发人员的水平和涵养有关系,即便在C#这种良好的高级对象语言的基础上,部分开发人员仍然可以写糟糕的难以读懂的语言结构来。因此,开发人员不仅仅是要学会在高级语言上使用对象编程,并更需要深刻理解对象概念,最终能将这种概念运用到不同的语言中来,使其语言结构,模块化,对象化。 在我刚刚接触Perl的时候,我认为这种语言根本无法写出对象化的语言结构。因此,我对此有诸多抱怨。但随着学习的深入,Perl一样可以使用对象的概念来构件合适和清晰的语言结构。 我把最后测试的代码先贴上来: use filehandle::filehandler; use filehandle::catchWorkerId; print "\nTEST fildehander base class \n\n"; my $filehandler = filehandler->new("c:\\test2.ini"); print $filehandler->getDealedStrings(); print "\nTEST fildehander sub-class \n\n"; $filehandler = catchWorkerId->new("c:\\test2.ini"); print $filehandler->getDealedStrings(); $filehandler->exportToFile("C:\\test2_new.ini"); filehandler.PM和catchworkerId.PM是我们重要的两个Module(class)。fileHandler类是父类并完成了一个文件解析的基本动作: 打开文件 每行读取 解析字符串并保存在类的数组变量里面 导出到合适的文件中 这样我们就可以只在子类里面完成需要变动的部分。请看子类代码catchworkId.PM package catchWorkerId; @ISA = qw(filehandler); use strict; use warnings; sub convert { my ($self,$linetext) = @_; my $pattern = "[a-z0-9]{9}[(]"; my @a; if(@a=($linetext =~/$pattern/gio)) { $a[0]=~s/[(]//g; return (1,$a[0]); } return (0,""); } 1; 代码说明
子类代码只是完成一个方法convert,它的输入是一个$linetext 字符串标量,我们进行正则表达式的判断,如果满足匹配则返回true+替换后的$linetext,如果不满足就返回false+空字符串。 如果在C#这类对象强类型语言中我们可以这样定义: bool convert(string linetext, out string convetedlinetext) { //implemenet code } 由于Perl是一种解释性非类型语言,因此我们需要变通的实现这一功能。 所以,如何在新的概念情况下,用旧有语言来实现特定的功能,就需要开发人员的创新能力,这些东西不会在教程上讲述,而需要开发人员自己的摸索。 你看通过类的继承的方式,我们在子类只定义函数就完成我们预设目标。需要注意这一句: @ISA = qw(filehandler); 它的意思是,引入filehandler.PM的函数,首先在catchWorkerId中查找调用函数,如果没有找到,会继续在filehandler.pm中查找。通过这种方式,我们完成了变相实现了类的继承。
这里给出父类的实现:filehandler.PM package filehandler; use strict; use warnings; #new sub new { my($class, $filename) = @_; my $self ={ _filename =>$filename }; my @ss; $self->{_dealedStringArray}= \@ss; return bless($self,$class); } #really open file sub getDealedStrings { my($self) = @_; open (FILEHANDLE,$self->{_filename})|| die("can't open file: $self->{_filename}"); #start to deal string line by line! while(<FILEHANDLE>) { $self->handleLine($_); } close (FILEHANDLE); return @{$self->{_dealedStringArray}} ; } #deal string line by line sub handleLine { my ($self,$linetext) = @_; my @result = $self->convert($linetext); if($result[0]==1) { $self->_addstring($result[1]); } } #You can write a override function in sub class sub convert { my ($self,$old) = @_; $old = "CONVERTED STRING:" .$old; return (1,$old); } #add the dealed string into a array. sub _addstring { my ($self,$linetext) = @_; my @a =@{ $self->{_dealedStringArray}}; push(@a, $linetext."\n"); @{$self->{_dealedStringArray}} = @a; } #output converted file sub exportToFile { my($self,$newFileName) = @_; open FILEHANDLE ,">$newFileName" || die("can't create file : $newFileName"); for(my $i=0;$i<@{$self->{_dealedStringArray}};$i++) { print FILEHANDLE "${$self->{_dealedStringArray}}[$i]"; } close FILEHANDLE; } 1; 这里不在具体讲Perl 对象编程的概念,大家可以变参考背景知识里面推荐的O'Reilly - Advanced Perl Programming,边看本实例,一定会有所心得。 |
请发表评论