免费注册 查看新帖 |

Chinaunix

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

Perl Moose Inheritance Constructor Destructor [复制链接]

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-11-13 10:28 |只看该作者 |倒序浏览
本帖最后由 fender0107401 于 2013-11-13 19:58 编辑

有个问题,我有点想不清楚。

那就是在 Perl 里面,我使用 Moose 的时候 derived_class 的 constructor 和 base_class constructor 之间的关系问题。

显然,在Perl这种高级语言里面,没有必要讨论copy constructor,所以此处不考虑copy constructor。

示例代码:
base_class.pm

  1. package base_class;

  2. use v5.14;

  3. use Moose;

  4. has 'foo' => (isa => 'Str', is => 'rw');

  5. sub BUILD
  6. {
  7.     my $this = shift @_;

  8.     $this->generate_foo;
  9. }

  10. sub DEMOLISH
  11. {
  12.     # Nothing.
  13. }

  14. no Moose;

  15. 1;

复制代码
derived_class.pm
  1. package derived_class;

  2. use v5.14;

  3. use Moose;

  4. extends 'base_class';

  5. sub BUILD
  6. {
  7.     # Nothing.
  8. }

  9. sub DEMOLISH
  10. {
  11.     # Nothing.
  12. }

  13. sub generate_foo
  14. {
  15.     my $this = shift @_;
  16.     my $foo  = 'Hi, I am foo.';

  17.     $this->foo($foo);
  18.     return $this;
  19. }

  20. sub show_foo
  21. {
  22.     my $this = shift @_;

  23.     print $this->foo;
  24.     print "\n";
  25. }

  26. no Moose;

  27. 1;
复制代码
main.pl
  1. #! /usr/bin/perl

  2. use v5.14;

  3. use derived_class;

  4. my $derived_ob = derived_class->new;

  5. $derived_ob->show_foo;
复制代码
run result
  1. ./main.pl
  2. Hi, I am foo.
复制代码
  • 我确定的东西:

    • derived_class的对象,在创建的时候,是会调用base_class里面定义的BUILD函数的。
    • derived_class的对象,在销毁的时候,是会调用base_class里面定义的DEMOLISH函数的。

  • 我发现的问题:

    在上面的示例代码里面,bass的BUILD函数会调用generate_foo来设定foo的初始值,但是generate_foo这个函数是定义在derived_class里面的。由于derived_class的对象在调用自己的BUILD的时候会调用到base_class的BUILD,而base_class的BUILD会调用到generate_foo,所以foo的值被设定了。

    换句话说,base_class的BUILD是可以调用到derived_class里面的generate_foo函数的。我感觉很疑惑,毕竟generate_foo是定义在derived_class里面的。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
2 [报告]
发表于 2013-11-13 11:19 |只看该作者
似乎用role来实现更加好一点。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
3 [报告]
发表于 2013-11-13 12:30 |只看该作者
C++里面的继承都是先调用父类的constructor,然后在调用子类的constructor。

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
4 [报告]
发表于 2013-11-13 12:39 |只看该作者
回复 2# fender0107401


    创建对象只在 bless 那一步就完成了,又不是强类型语言调用方法都是在运行时查找的,当然可以调用子类的方法。另一方面如果你另一个子类没实现这个 generate_foo 在运行时会报方法不存在的错误(如果没定义 sub AUTOLOAD 的话)

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
5 [报告]
发表于 2013-11-13 12:42 |只看该作者
你心中正统的 OO 是不是要在 base_class 里面定义个 sub generate_foo { die "not implemented" }

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
6 [报告]
发表于 2013-11-13 13:38 |只看该作者
回复 4# zhlong8

我也说不好怎么回事,总觉得有点问题,有想不明白。

貌似Perl的继承是这样的:首先,子类继承所有父类的东西;然后,运行一下父类的BUILD;然后,再运行一下子类自己的BUILD。  

C++里面的class必须是定义完整的,不能调用不存在的method。

但是Perl完全不是,Perl允许一个class里面调用不存在的method。这时,只要不运行那部分代码,就不报错;或者,有一个class继承了这个class并且实现了那个不存在的method,然后instanciate子类的时候,也可以运行。

我这几天思考了不少类似的问题。

“解释型语言”和“编译型语言”的差别还是很大的。

我感觉“解释型语言”都是遇到问题时才报错,可能是因为性能的原因。

但是编译型语言在编译阶段,编译器就可以检查所有代码,如果在C++里面有一个class调用了一个没有被定义的method,那么就会是一个编译错误。

论坛徽章:
89
水瓶座
日期:2014-04-01 08:53:31天蝎座
日期:2014-04-01 08:53:53天秤座
日期:2014-04-01 08:54:02射手座
日期:2014-04-01 08:54:15子鼠
日期:2014-04-01 08:55:35辰龙
日期:2014-04-01 08:56:36未羊
日期:2014-04-01 08:56:27戌狗
日期:2014-04-01 08:56:13亥猪
日期:2014-04-01 08:56:02亥猪
日期:2014-04-08 08:38:58程序设计版块每日发帖之星
日期:2016-01-05 06:20:00程序设计版块每日发帖之星
日期:2016-01-07 06:20:00
7 [报告]
发表于 2013-11-13 13:38 |只看该作者
回复 5# zhlong8

话说,这招我还真想过。


   

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
8 [报告]
发表于 2013-11-13 14:47 |只看该作者
主要原因还是不知道对象的类型,一方面 C++ 中编译器可以知道一个类所有的方法,对象的类型通过声明或推断也可以知道,自然可以在编译期检测。而且有能力把方法调用改写成函数调用,提高性能


论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
9 [报告]
发表于 2013-11-13 14:53 |只看该作者
JVM 的模型跟 Perl 应该是一样的,要不它上面也没法建 Jython Jruby 这些,只不过 Java 给对象套上了个类型系统就显得很高级很严谨了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP