为什么 'translate' 这个词在搞乱 irb?

Why word 'translate' is messing irb?

我不明白为什么我的方法 translate 取消定义 start_with? 方法并且在 irb 中弄乱了一些东西,所以我只能通过按 Ctrl[=28= 退出 irb ]+d,不是exitquit

>> "hello".respond_to?(:start_with?)
=> true
>> def translate(string)                                                                                                                   
>>   if string.start_with?("a", "e", "i", "o", "u")
>>     string += "ay"                                                                                                                      
>> end
>> end
NoMethodError: undefined method `start_with?' for #<RubyVM::InstructionSequence:0x00000001d4c960>
        from (irb):3:in `translate'
        from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> "hello".respond_to?(:start_with?)                                                                                                       
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding@(irb)>:RubyVM::InstructionSequence
        from (irb):3:in `translate'
        from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> exit
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding@(irb)>:RubyVM::InstructionSequence
        from (irb):3:in `translate'
        from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> quit
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding@(irb)>:RubyVM::InstructionSequence
        from (irb):3:in `translate'
        from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>>  

我尝试了两个不同的工作区,效果是一样的。
我的Ruby和Rails版本是:

~/workspace $ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
~/workspace $ rails -v
Rails 4.2.2

来自 我知道许多 I18N 库都使用 translate 这个词,所以这是我唯一的怀疑,因此这个问题的标题。但是作为初学者,我看不出有什么关系。

这是一个理论

  • 您的设置中可能有一个全局函数 translate
  • irb 打印输出
  • 时,以指令序列作为参数调用此函数
  • 因此,当您重新定义 translate 打印输出中断时

NoMethodError: undefined method并不是说这个方法已经全局未定义,而是被发送给一个不理解它的对象

你可以通过执行来测试我的理论

method(:translate)

如果你得到一个结果,那么translate已经被定义了,你不能重新定义它!

现在如果你想知道哪个gem定义了这个函数,安装pry gem(这是一个更好的irb)并使用$命令查看在该方法的文件和源代码处

# Use this command in pry to see location and source code
$ translate

这是 YARV 2.4.0 fixed 中的一个错误。

如果您没有 YARV 2.4.0,提交消息会提到以下解决方法:

class << RubyVM::InstructionSequence
  def translate; end
  undef translate
end

请注意,其他实现不受影响,只有 YARV。