设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
12
返回列表 发新帖
楼主: 六祈
打印 上一主题 下一主题

[已经解决] 在父类和子类中同时alias同名方法竟然会出错,啥原因

[复制链接]

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

11
 楼主| 发表于 2010-7-22 16:17:59 | 只看该作者
本帖最后由 六祈 于 2010-7-22 16:56 编辑

回复 六祈 的帖子
真理貌似如下:



一旦一个类中alias x y了
那么遇到任何调用x的方法,都会去寻找y
于是27行后面调用的old_xxx去调用原来的xxx,而原来的xxx含有super去调用父类中的xxx,父类也有alias,xxx去调用old_xxx,然后悲剧发生了,子类在自己的环境中寻找xxx,于是参数异常,如果不异常,则死循环(父子类一直互相调用)

   
谢谢紫苏和IamI两位大人的答疑解惑~bow~
   

点评

应该不能说是调用x会找y吧,而是y中如果有super,alias x y,那么调用x就会找父类的y吧。然后因为y中有x,所以又去找子类的x,结果就参数不符。  发表于 2010-7-23 10:35
如果参数吻合,那父类的 xxx 继续调用 old_xxx,而 old_xxx 正是 xxx 它本身,所以会抛出栈层次太深异常  发表于 2010-7-22 17:12
你这里没有 super 吧,27 行之后 old_xxx 就保存了 xxx 的一份拷贝,调用 old_xxx 就是调用父类的 xxx,父类的 xxx 需要 4 个参数,而你在子类重定义的 initialize 中传递了 0 个,所以有参数异常;如果参数吻合,父   发表于 2010-7-22 17:11
既然你有irb,何妨不跑一下呢?我这里却是2哦~  发表于 2010-7-22 16:26
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1195
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

12
发表于 2010-7-22 16:34:03 | 只看该作者
本帖最后由 DeathKing 于 2010-7-22 16:38 编辑
  1. irb(main):001:0> class A;def a; puts 1;end; alias :c :a;end
  2. => nil
  3. irb(main):002:0> class B<A
  4. irb(main):003:1> def b
  5. irb(main):004:2> puts 2
  6. irb(main):005:2> end
  7. irb(main):006:1> puts respond_to? :c
  8. irb(main):007:1> puts respond_to? :a
  9. irb(main):008:1> end
  10. false
  11. false
  12. => nil
  13. irb(main):009:0> B.superclass
  14. => A
复制代码
不知道是不是因为Ruby 1.9.1的缘故 - -

ri Module#respond_to?

获取帮助(respond_to? 属于元编程(反射机制)的范畴,获取是否可以使用从父类继承的方法。)

我唯一可以说的是,可能Ruby 1.9.1对alias做了手脚,alias方法后,子类就不能使用从父类继承的方法了?但是实例却可以调用?

点评

你这个respond_to?的环境不对,当前self=B(是一个类对象,而c和a都是实例方法)  发表于 2010-7-22 16:45

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
13
发表于 2010-7-22 17:08:05 | 只看该作者
发现我之前说错了一句话,在原帖编辑了一下,红色部分是修改过的……||||
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1195
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

14
发表于 2010-7-22 17:33:16 | 只看该作者
本帖最后由 DeathKing 于 2010-7-22 17:42 编辑

回复 DeathKing 的帖子
  1. class A
  2.   def a
  3.     puts 1
  4.   end
  5.   alias :b :a
  6.   undef :a
  7. end

  8. A.new.b
  9. #=> 1
复制代码
才交完水电气回来看到
   




一旦一个类中alias x y了
那么遇到任何调用x的方法,都会去寻找y

如果真这样的话
假设y方法已定义
alias x y
def y
x
end
这样就会死循环了。

点评

自己用就别考虑兼容性,自己重载方法。如果像这样弄得很复杂反而不好维护。  发表于 2010-7-22 17:52
其实我是写了一楼的脚本,出错了,虽然有办法解决,但是搞不懂怎么回事很苦恼。现在总算明白了  发表于 2010-7-22 17:50
真有必要就用模块来Mixin吧……  发表于 2010-7-22 17:49
汗,你觉得这样有必要么?  发表于 2010-7-22 17:48
其实我自己已经明白了。。。你看下15楼,是一个很简化版本的子类调用父类,父类调用方法时使用的是子类的context  发表于 2010-7-22 17:47
回复 支持 反对

使用道具 举报

Lv2.观梦者

旅之愚者

梦石
0
星屑
275
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

15
 楼主| 发表于 2010-7-22 17:36:52 | 只看该作者
猜猜看这个结果
  1. class A
  2. def a
  3. b
  4. end
  5. def b
  6. puts 2
  7. end
  8. end
  9. class B < A
  10. def c
  11. puts 3
  12. end
  13. alias b c
  14. end

  15. puts B.new.a
复制代码
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
462 小时
注册时间
2007-7-30
帖子
643
16
发表于 2010-7-23 08:55:26 | 只看该作者
是3嗎?

点评

yes  发表于 2010-7-23 20:42
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-12-27 05:50

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表