现在的位置: 首页 > 综合 > 正文

Perl 面向对象编程时 bless()函数的使用

2018年02月14日 ⁄ 综合 ⁄ 共 2272字 ⁄ 字号 评论关闭

1、说明
本程序演示了在Perl中如何进行面向对象编程:演示程序包含两个文件:person.pl 和 person.pm,把 person.pl 和 person.pm 放在当前目录下,运行"perl person.pl"即可以看到结果。person.pm定义了名为person的类。person.pl中创建了person类的实例,并测试了person的成员方法。

2、person.pm的内容

  1. #!/usr/bin/perl -w
  2. package person;
  3. use strict;
  4. sub new {
  5.         my $class = shift();
  6.         print("CLASS = $class\n");
  7.         my $self = {};
  8.         $self->{"name"} = shift();
  9.         $self->{"sex"} = shift();
  10.         bless $self, $class;
  11.         return $self;
  12. }
  13. sub getName {
  14.         my ($self) = @_;
  15.         return $self->{"name"};
  16. }
  17. sub setName {
  18.         my ($self, $name) = @_;
  19.         $self->{"name"} = $name;
  20. }
  21. sub getSex {
  22.         my ($self) = @_;
  23.         return $self->{"sex"};
  24. }
  25. sub setSex {
  26.         my ($self, $sex) = @_;
  27.         $self->{"sex"} = $sex;
  28. }
  29. 1;

注意new方法中的最后一行:

  1. return $self;

我发现去掉这条语句程序还是可以正常运行,有谁知道为什么?

3、person.pl的内容

  1. #!/usr/bin/perl -w
  2. use strict;
  3. use person;
  4. sub main()
  5. {
  6.         my $tom = person->new("Tom", "male");
  7.         my $kiss = person->new("Kiss", "female");
  8.         my @persons = ($tom, $kiss);
  9.         for my $p (@persons) {
  10.                 printf("NAME: %s\tSEX: %s\n", $p->getName(), $p->getSex());
  11.         }
  12. }
  13. &main();

 

4、程序运行结果

QUOTE:
CLASS = person
CLASS = person
NAME: Tom      SEX: male
NAME: Kiss      SEX: female

5、当调用person->new("Tom", "male")时发生了哪些事情?
下面我们将重点分析下面的代码,为了查看方便,我把它粘贴过来了:

  1. sub new {
  2.         my $class = shift();
  3.         print("CLASS = $class\n");
  4.         my $self = {};
  5.         $self->{"name"} = shift();
  6.         $self->{"sex"} = shift();
  7.         bless $self, $class;
  8.         return $self;
  9. }
  • 当调用person->new("Tom", "male")时,有3个参数被传递给person中的new函数,它们分别是: 类的名称"person"(这是一个隐含参数)、"Tom"、"male"。
  • 语句my $class = shift();获得第一个参数
  • 语句my $self = {};创建一个哈希表对象的引用
  • 语句$self->{"name"} = shift(); 把传进来的第二个参数存入到哈希表中。
  • 语句$self->{"sex"} = shift(); 把传进来的第三个参数存入到哈希表中。
  • 语句bless $self, $class,我把bless理解为"把类型信息和变量绑定" :
    • $self是一个指针,在这里指向了一个哈希表对象的引用
    • $class是一个字符串,在这里是person类的名字
    • 在perl中,根据类的名字可以查找到这个类所有的成员方法和成员变量,因此类的名称就代表了类的类型信息!
    • 所谓bless就是把 person类的类型信息 赋予 哈希表对象的引用

  • 语句return $self;则返回哈希表对象的引用

这里我有两个问题:

  • 为什么我把person->new()中最后一条return $self;语句去掉后,程序仍然可以正确运行了?
  • person.pm中的最后一条语句1;不可以遗漏,否则在person.pl中加载person.pm模块失败,我的理解是在perl.pl中use person时,会去尝试执行person.pm脚本,根据返回值判断初始化是否成功。

6、后记
通过一段时间的摸索,我已经基本熟悉了perl的面向过程编程,我打算学习perl的OO编程和引用的概念,这是我编写的第一个perl OO程序,原先我以为编写一个Person类是非常容易的,后来发现编写一个最简单的OO程序还是挺麻烦的,这里要感谢zhang1120,他编写的MyCGI模块有很大的参考价值

在编写过程中,我主要遇到了如下的困难,给初学者参考:

  • 网上的参考资料质量太差而且排版差,要找一个简单的、完整的例子都不容易。
  • 理解bless的概念。bless关键字的名称非常不直观,"把类型信息和变量绑定" 与 "祝福" 有什么联系?如果把bless改为bind,就不用初学者那么费劲的去猜bless的含义了。
  • 在person.pm的末尾要加上1;, 不加这条语句的话,use person会失败。

抱歉!评论已关闭.