免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 19378 | 回复: 10
打印 上一主题 下一主题

PERL面向对象起步! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-24 00:22 |只看该作者 |倒序浏览
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、程序运行结果
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会失败。


[ 本帖最后由 DennisRitchie 于 2007-8-24 02:40 编辑 ]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
2 [报告]
发表于 2007-08-24 07:56 |只看该作者
perldoc perlsub
没有 return 的情况下,
sub 的最后一条语句的返回值,
也就是 sub 的返回值。

关于 1; 的问题你猜测得不错,
use 就是会判断最后一个语句的返回值,
如果失败就认为模块初始化失败。

至于你说网上的参考资料质量太差,
这个不太厚道吧。我认为大骆驼还是很不错的。例子也多。
至于 bless 的问题,我觉得很好理解,至少比 setType 一类的冷冰冰的要好记多了。
bind 是 socket 里的原语,这个已经有了。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
3 [报告]
发表于 2007-08-24 08:17 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2007-08-24 09:59 |只看该作者
这种语法,根本看不出OO在分析问题方面的优势。

用Perl就别想OO了。

论坛徽章:
0
5 [报告]
发表于 2007-08-24 17:32 |只看该作者
原帖由 flw 于 2007-8-24 07:56 发表 perldoc perlsub
没有 return 的情况下,
sub 的最后一条语句的返回值,
也就是 sub 的返回值。

关于 1; 的问题你猜测得不错,
use 就是会判断最后一个语句的返回值,
如果失败就认为模块初始化失败。

谢谢!我觉的把1;改为return 1;更容易理解一点。

至于你说网上的参考资料质量太差,
这个不太厚道吧。我认为大骆驼还是很不错的。例子也多。

我主要是指网上发的帖子。

至于 bless 的问题,我觉得很好理解,至少比 setType 一类的冷冰冰的要好记多了。

学习perl语言时,每个人原有的基础和理解能力都是不一样的。客观事实是:至少在这个论坛里面,有很多人问过bless的问题,把bless改为能够反映bless含义的关键字(如 setType),是有助于我们理解它的概念的。

论坛徽章:
0
6 [报告]
发表于 2010-09-30 07:45 |只看该作者
挺麻烦的OO

论坛徽章:
0
7 [报告]
发表于 2010-09-30 14:37 |只看该作者
平常的工作编写 还用不上OO,可能是思维定固了。悲哀

论坛徽章:
0
8 [报告]
发表于 2012-09-13 16:49 |只看该作者
谢谢楼主,通过你的例子,我理解的快多了,之前从书上看没有一个全景的盖帽,你的例子很棒。

补充了下你的set函数的用法:
  1. > vi person.pl   

  2. #!/usr/bin/perl -w
  3. use strict;
  4. use person;

  5. sub main()
  6. {
  7.         my $tom = person->new("Tom", "male");
  8.         my $kiss = person->new("Kiss", "female");

  9.         my @persons = ($tom, $kiss);
  10.         for my $p (@persons) {
  11.                 printf("NAME: %s\tSEX: %s\n", $p->getName(), $p->getSex());
  12.                 }

  13.         for my $p (@persons) {
  14.                 $p->setName($p->getName." newname");
  15.                 $p->setSex($p->getSex." newsex");
  16.                 printf("NAME: %s\tSEX: %s\n", $p->getName(), $p->getSex());
  17.         }

  18. }

  19. &main();
复制代码
  1. > perl person.pl
  2. CLASS = person
  3. CLASS = person
  4. NAME: Tom       SEX: male
  5. NAME: Kiss      SEX: female
  6. NAME: Tom newname       SEX: male newsex
  7. NAME: Kiss newname      SEX: female newsex
复制代码
回复 1# DennisRitchie


   

论坛徽章:
0
9 [报告]
发表于 2013-05-13 17:44 |只看该作者
Thx,一直都对这个望而却步,这个例子非常好

论坛徽章:
0
10 [报告]
发表于 2013-10-28 16:26 |只看该作者
例子分析很好,简洁易懂。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP