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

fsword · June 16, 2012 · Last by bhuztez replied at June 17, 2012 · 4043 hits
class Class; alias oldNew new; def new(*args); o=oldNew(*args); p "#{o} is defined" end; end

然后试试看怎么退出

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

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

Unknow user #4 June 16, 2012

看不懂。。。

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

#5 楼 @jjym

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

Unknow user #7 June 16, 2012

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

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

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

Unknow user #9 June 16, 2012

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

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

#10 楼 @jjym

我觉得唯一的解释:

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

Unknow user #11 June 16, 2012

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

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

例如:

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

#12 楼 @jjym

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

例如:

class A
end
#等价于
A = Class.new
Unknow user #14 June 16, 2012

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

#15 楼 @jjym

就是这个 new. 没错啦。

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

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

You need to Sign in before reply, if you don't have an account, please Sign up first.