Perl 面向对象编程的力量
使用 Perl 的面向对象接口扩展现有类型
引言
利用 Perl 面向对象接口的力量,可以以面向对象的方式扩展现有的 Perl 类型。
背景
Perl 是一种很棒的语言,但其中一个最大的问题是该语言的核心并非面向对象,这导致了类似的情况:
my @foo = (); push(@foo, "bar")
虽然这本身可能没有问题,但 Perl 在其函数调用中存在一些不一致之处。有时被修改的对象是第一个参数,有时不是。让数组本身调用 push 避免了提供不必要的参数。你还可以添加你自己的函数,例如从数组中提取所有唯一元素。
创建模块
对于这个例子,我不会包含你在模块中找到的所有“正常”功能,例如版本、pod 等。
package Array; use strict; #create our constructor sub new() { my ($package, @args) = @_; my @internal = (); @internal = @args if defined @args; my $self = \@internal; return bless($self, $package); }
现在我们有了构造函数,可以通过调用 new Array()
来创建一个新的数组。我们可以创建一个空数组,或者在创建时将参数以列表或标量上下文传递给我们的构造函数来填充数组。由于我们的对象本身只是对数组的引用,我们可以通过将对象包装在 @{}
中像使用普通数组一样使用它。
$array = new Array;
print @{$array};
现在我们有了对象,最好为其添加一些方法。
sub push() { my ($self, $value) = @_; push(@{$self}, $value); }
现在我们可以使用 $array->push("Blah")
将一个对象推送到数组的末尾。
可以针对你想要的任意数量的数组函数重复此操作,例如 shift
、pop
等。你甚至可以添加你自己的函数,例如 unique
函数。
sub unique()
{
my $self = shift;
my %dups = undef;
return grep(!$dups{$_}++, @{$self});
}
当前的所有函数都返回一个普通的数组,但完全有可能返回一个数组对象。
return new Array(grep(!$dups{$_}++, @{$self}));
Using the Code
使用示例代码非常简单use lib '/path/to/library';
use Array;
$array = new Array;
$array->push("New Item");
关注点
虽然不切实际地更改 Perl 中的每种数据类型并添加所有相关函数,但你可能会喜欢在 Perl 代码中使用更面向对象的风格。这种技术在小型脚本中没有太大意义,但在大型项目中可能非常有用,特别是由于你可以添加自己的方法。
历史
- 2008年3月14日星期五 -- 创建