2013-02-17 36 views
1

当我没有为类定义赋予'initialize'方法时,实际上看到的是什么,那么你所说的类应该调用"Object#initialize",这里我试图自定义并查看它是否已被调用。通过这种方法,我得出了一个结论(虽然这是错误的),当我键入“ob = A。new”时,我可以重载Object#initialize方法。但是,所有结果都以下面的例外结束。然后我认为我在自定义中做了错误的事情。所以我尝试在异常块中创建对象创建,并且当我键入“begin”并按下“ENTER”时 - 我得到了同样的错误。当对象#初始化过载时Ruby中IRB输出混乱

>> class A 
>> def Object.new initialize 
>> p "hi" 
>> rescue 
>> end 
>> end 
=> nil 
>> begin # <~~~ Here I have pressed on ENTER 
"hi" #<~~~~ How was it print out? 
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:94:in `Token': undefined method `set_backtrace' for "hi":String (NoMethodError) 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:348:in `block in lex_init' 
    from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call' 
    from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io' 
    from /usr/lib/ruby/1.9.1/irb/slex.rb:221:in `match_io' 
    from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels) in each_top_level_statement' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch' 
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement' 
    from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input' 
    from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start' 
    from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch' 
    from /usr/lib/ruby/1.9.1/irb.rb:69:in `start' 
    from /usr/bin/irb:12:in `<main>' 
@ubuntu:~$ 

现在我的问题是 -

  • 如何有 “喜” 被打印?

  • 上面打印的错误的原因是什么?

  • 如果这样的initialize定义不被允许,那么为什么在我用类定义结束后错误不会出现?

编辑

按@casper我试过如下:

>> def Object.new 
>> p "hi" 
>> end 
=> nil 
>> begin 
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:96: stack level too deep (SystemStackError) 

但这里没有"hi"印刷回来。

那么是什么让“嗨”在第一种情况下打印回来?

+1

此外,用一段代码开始一个问题没有解释是不好的。我认为这也很粗鲁。读者应该怎么处理它?始终以普通文本开始。代码应该在文本之前说明它在上下文中的相关性以及读者应该如何处理它。 – sawa 2013-02-17 20:50:02

+1

@sawa我编辑了我的描述。感谢您的后期提示。 – 2013-02-17 20:55:14

回答

3

你究竟想要做什么?你刚刚重新定义了Object.new,所以毫不奇怪你会让一切都变得不合时宜。

基本上可以通过只获得同样的效果:

>> def Object.new 
>> end 
>> [press enter] 
KABOOM 

原因是印刷"hi"是有人刚刚打电话Object.new,可能是irb REPL循环,它预期的目标,而是它得到gobledygook 。

你也可以试试这个:

def Object.new *args 
    p args 
end 

你会看到有趣的东西。但是,在此之后,您将无法退出irb或做任何有用的事情。再说一遍:你刚打破Object

为了使一些感觉,你应该阅读:
In Ruby, what's the relationship between 'new' and 'initialize'? How to return nil while initializing?

然后你可以试试这个:

class Object 
    class << self 
    alias :old_new :new 
    end 
end 

现在你可以这样做:

def Object.new *args 
    p args 
    old_new *args 
end 

这亿韩元因为你仍然在调用它的旧版本,所以不会打破new。但是,每当有人拨打new时,您现在都会打印出内容。

+0

但定义是否有效?那为什么错误来了? – 2013-02-17 20:30:14

+1

呃..这是一个有效的定义,但是你正在修改一个正在运行的程序。这个程序是'irb'。通过改变Object.new,你在irb运行的时候破坏了irb:irb是一个Ruby程序,你只需在Ruby上重新定义'new'就可以打破基本的基本对象。 – Casper 2013-02-17 20:38:33

+0

@ user2060534查看我的编辑 – Casper 2013-02-17 20:56:39