新手问题 no implicit conversion of nil into String (TypeError)

kooder · 2017年09月19日 · 最后由 msg7086 回复于 2017年09月20日 · 5613 次阅读

在 irb 2.2.6 里面输入如下代码(摘自《元编程》)

class Fixnum
  alias :old_plus :+
  def +(value)
    self.old_plus(value).old_plus(1)
  end
end

发现会报以下错误, in `block in expand_prompt': no implicit conversion of nil into String (TypeError)

请教大家,谢谢!

并没有出现问题啊。

我的出错信息是这样的。当前在 Windows 上使用的是 ruby 2.2.6, 试过 ruby 2.4.2, 结果是一样的。是不是哪里配置不对?

irb(main):001:0> class Fixnum
irb(main):002:1> alias :old_plus :+
irb(main):003:1* def +(value)
irb(main):004:2> self.old_plus(value).old_plus(1)
irb(main):005:2> end
irb(main):006:1> end
=> :+
C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1716:in `block in expand_prompt': no implicit conversion of nil into St
ring (TypeError)
        from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1696:in `each'
        from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1696:in `expand_prompt'
        from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1784:in `rl_expand_prompt'
        from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:1809:in `rl_set_prompt'
        from C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb:4821:in `readline'
        from C:/Ruby22/lib/ruby/site_ruby/2.2.0/readline.rb:45:in `readline'
        from C:/Ruby22/lib/ruby/2.2.0/irb/input-method.rb:150:in `gets'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:469:in `block (2 levels) in eval_input'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:623:in `signal_status'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:468:in `block in eval_input'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:188:in `call'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:188:in `buf_input'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:103:in `getc'
        from C:/Ruby22/lib/ruby/2.2.0/irb/slex.rb:205:in `match_io'
        from C:/Ruby22/lib/ruby/2.2.0/irb/slex.rb:75:in `match'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:282:in `token'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:264:in `lex'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:235:in `block (2 levels) in each_top_level_statement'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `loop'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `catch'
        from C:/Ruby22/lib/ruby/2.2.0/irb/ruby-lex.rb:230:in `each_top_level_statement'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:485:in `eval_input'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:395:in `block in start'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `catch'
        from C:/Ruby22/lib/ruby/2.2.0/irb.rb:394:in `start'
        from C:/Ruby22/bin/irb:11:in `<main>'

但是在 Linux 上试了 ruby 1.8.7,功能正常,输出如下,和上面的输出相比,=>:+ 变成了 => nil, 这又是什么原因?

irb(main):001:0> class Fixnum
irb(main):002:1> alias :old_plus :+
irb(main):003:1* def +(value)
irb(main):004:2> self.old_plus(value).old_plus(1)
irb(main):005:2> end
irb(main):006:1> end
=> nil

因为例子中的代码改写了 + 的结果为正确结果 +1,因此当定义完 + (method)后,C:/Ruby22/lib/ruby/site_ruby/2.2.0/rbreadline.rb 里的表达式做加法运算时出现了对数组索引越界的错误。但是为何有些环境下就正常运行呢(比如 Linux)?

G.O.A.Tzz 回复

你的运行环境是怎样的呀?

kooder 回复

Ruby 2.3.1 for mac.敲 ruby,linux 系统支持的好一些,不要纠结于一个例子在平台上是否成功运行,明白代码的意思就好。

因为这个交互式命令行本身也会被你的代码改变吧。

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