# test.pl
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(" $itemn");
}
}
package TestHash;
sub test {
my $this = shift();
print("nIn TestHash::test()n");
print("Hash:n");
while (my ($key, $value) = each %{$this}) {
printf(" %-4s = %sn", $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
从上面的示例中可以看到,分别将3种类型的引用转变为对象。之所以要把类写成3个而非1个,主要是为了在Test里输出不同类型的数据。
类和对象的成员函数
成员函数就是在package中定义的子程序。成员函数是没有静态和非静态之分的,但我宁愿大家都把它看作是静态函数,因为虽然它即可以当作类成员函数来调用,也可以当用对象成员函数来调用,但在当作对象成员函数来调用的时候,Perl偷偷的传入了对象引用。这也解释了为什么通常成员函数里的第一句话往往是
my $this = shift();
当然,这里的$this只是一个局部变量,而不是关键字,你也可以用别的名称来代替它。比如很多人就喜欢用$self,或者$me等。
假如,对于一个成员函数,分别用类和对象来对它进行调用,会有什么不一样呢?再看一个示例:
# test.pl
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(...)]
从结果可以看出来,不管哪种方法调用,第一个参数都是Perl偷偷传递进去的。如果是类调用,则第一个参数是该类。如果是对象调用,第一个参数是该对象。因此,只需要将ref($this)的结果和类名进行比较就清楚是哪种调用了。所以,一个容错性较好的成员函数,一开始要判断传入的第一个参数,比如









