Ruby irb 里面执行一下这个试试?

fsword · 2012年06月16日 · 最后由 bhuztez 回复于 2012年06月17日 · 4012 次阅读
class Class; alias oldNew new; def new(*args); o=oldNew(*args); p "#{o} is defined" end; end

然后试试看怎么退出

嘿嘿,好像只有这样,然后还要 kill 一下

#2 楼 @fsword 这个应该就属的猴子补丁了吧,把 new 方法重新定义了,class 应该在祖先链的最下端,这样就相当于直接把入口给改了,取消 alias 也取消不了

匿名 #5 2012年06月16日

看不懂。。。

本人对楼主这段代码的评价是:插入太深。

#5 楼 @jjym

打开 Ruby 的 Class 核心类,并且覆写了 Class 类内的那个 new 方法,这个 new 方法在创建一个类对象时,会被自动调用. 而打开核心类这个操作,虽然没有创建一个新的 Class 类,不过也应该会调用 new 方法来应用最新的更改。形成了一个递归调用? @fsword , 大概是这意思吧?不过,我是没明白输出的那一大堆东西是什么玩意儿。我在 irb 下,我直接 C-c 就可以终止.(Emacs irb)

匿名 #8 2012年06月16日

#7 楼 @zw963 正常的执行环境下这段代码不会调用 new,也不会形成递归。可以用 ruby 命令执行这脚本看下便知

主要是不明白 irb 内部是怎么执行的 召唤@fsword 求解、、、

#8 楼 @jjym irb 的结构也挺复杂,我大概翻了一下,应该和系统钩子的相关代码无关,另外如果把 p 改为 puts 就可以正常退出了,怀疑是对别名进行解析的时候建立了新的类,然后就错了。 但是我不能理解的是,如果不创建新类自然没事,如果要创建新类,为什么又没有无限递归呢?

匿名 #10 2012年06月16日

#9 楼 @fsword 我也粗略看了下 irb 的源码,基本看不懂 我猜应该是 irb 每次运行一行的时候都要新建一些辅助对象,所以会打印到终端。 而且 irb 是从终端上读取命令,所以造成递归。。 我上面说的是 win 的情况,刚刚发现在 ubuntu 和 win 上执行的效果不一样

创建新类也不会递归,你重新定义方法时这两个方法名就已经指向不同的方法了

#10 楼 @jjym

我觉得唯一的解释:

首先,肯定存在递归,只不过,Ruby 解释器可以判断出来这个情形,因此立即终止,并返回 nil. 在 irb 下,首次运行也是返回 nil 的.(1.92) 再次运行,才会出来一堆东西,这中间的玄机,就不得而知了。

匿名 #12 2012年06月16日

#11 楼 @zw963 为什么会递归?

无论如何,在语法上,这就是一个 class 定义。

例如:

class A
end
#等价于
A = Class.new

#12 楼 @jjym

无论如何,在语法上,这就是一个 class 定义。

例如:

class A
end
#等价于
A = Class.new
匿名 #15 2012年06月16日

#14 楼 @zw963 这里没有任何的 new 或者 alias 之后的 class 定义,而且这个 alias 的是 new,不是 self.new。 其次即使有也不会递归

#15 楼 @jjym

就是这个 new. 没错啦。

至于是 new 或者你说的 self.new, 看从那个角度了。这个 new 即是 Class 类内的实例方法,又是任何 Class 对象的 new 方法。(对于类来说,就仿佛类的类方法一样)

诡异了,多次运行结果不一样。有时候输入 exit 退不出,现在输啥都直接退出了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号