ruby - object#initialize 重载时与 Ruby 中的 IRB 输出混淆

标签 ruby ruby-1.9.3

当没有为类定义提供“初始化”方法时,我实际上试图看到的是你所说的类应该调用 “Object#initialize”,我在这里尝试自定义和查看它是否已被调用。通过这种方法,我得出了一个结论(尽管那是错误的),当我输入“ob = A .new”时,是的,我可以重载 Object#initialize 方法。但一切都以以下异常。然后我以为我在自定义中做错了什么。所以我尝试在异常 block 中创建对象创建,当我键入“开始”并按“ENTER”时 - 我遇到了同样的错误。

>>  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:~$

现在我的问题是 -

  • “hi”是如何打印出来的?

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

  • 如果这样的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"

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

最佳答案

你到底想做什么?您刚刚重新定义了 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 时,您现在都会打印出一些东西。

关于ruby - object#initialize 重载时与 Ruby 中的 IRB 输出混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14924777/

相关文章:

ruby - 使用::访问模块方法:

ruby-on-rails - ActiveRecord 数组计数

css - 如何检测 SCSS 文件或其任何部分文件是否已更新

ruby - Rails 4 引擎是否自动加载引擎的 i18n 语言环境文件?

ruby-1.9.3 - 在 Ruby 中如何比较包含不同键格式(一些字符串,一些符号)的哈希是否相等?

ruby - 如何为 Ruby 安装 Selenium 和 Nokogiri?

Ruby:计算唯一排列的数量而不使用 .permutation 和数据集中的重复项

ruby - 如何 .{n} 和 ?<option> : works in `Regexp` on Ruby 1. 9.3 环境

installation - 如何使用rvm在OS_X 10.9上安装ruby 2.1.0? ( : osx/10. 9/x86_64/ruby 没有可用的二进制 ruby )

ruby - Anchor\z 和\G 在 Ruby 中是如何工作的?