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

kooder · September 19, 2017 · Last by msg7086 replied at September 20, 2017 · 5618 hits

在 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)?

Reply to G.O.A.Tzz

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

Reply to kooder

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

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

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