未定义的方法'&gt;' for nil:NilClass <nomethoderror> </nomethoderror>

时间:2013-11-03 09:18:26

标签: ruby methods operator-keyword

好的我有以下代码

 def update_state_actions
    states.each do |state|
      @state_turns[state.id] -= 1 if @state_turns[state.id] > 0 && state.auto_removal_timing == 1
    end
  end

现在排在......

 @state_turns[state.id] -= 1 if @state_turns[state.id] > 0 && state.auto_removal_timing == 1

它说错误

in 'block update_state_actions' : Undefined method '>' for nil:NilClass <NoMethodError>

错误的原因是什么? 如何将>视为一种方法,但它是一个逻辑运算符?

2 个答案:

答案 0 :(得分:51)

  

怎么来&gt;被认为是一种方法,但它是一个逻辑运算符?

没有问题。在Ruby中,当您编写类似1 + 2的表达式时,在内部将其理解为1.+( 2 ):在接收方#+上调用方法1并将2作为单个论点。另一种理解相同的方法是,您将消息[ :+, 2 ]发送到对象1

  

错误的原因是什么?

现在,在您的情况下,@state_turns[ state.id ]由于某种原因返回nil。因此,表达式@state_turns[state.id] > 0变为nil > 0,正如我之前所说,它被理解为在#>上调用nil方法。但是,您可以检查NilClass所属的nil是否没有定义实例方法#>

NilClass.instance_methods.include? :> # => false
nil.respond_to? :> # => false

NoMethodError例外因此是合法错误。通过引发此错误,Ruby会保护您:它会提前告诉您,@state_turns[ state.id ]不是您认为的那样。这样,您可以更早地纠正错误,并成为更有效的程序员。此外,可以使用begin ... rescue ... end语句挽救Ruby异常。 Ruby异常通常是非常友好和有用的对象,您应该学习如何在软件项目中定义自定义异常。

为了进一步扩展这个讨论,让我们看看你的错误来自哪里。当您编写类似nil > 10的表达式(实际上是nil.>( 10 ))时,Ruby开始在#>的查找链中搜索nil方法。您可以通过键入以下内容来查看查找链:

    nil.singleton_class.ancestors #=> [NilClass, Object, Kernel, BasicObject]

将在祖先链的每个模块中搜索该方法:首先,Ruby将检查#>上是否定义了NilClass,然后Object上是Kernel ,最后,BasicObject。如果在其中任何一个中找不到#>,Ruby将继续尝试method_missing方法,再次按顺序查找链的所有模块。如果即使method_missing未处理:>消息,也会引发NoMethodError异常。为了演示,让我们通过插入自定义消息在#method_missing中定义Object方法,而不是NoMethodError

class Object
  def method_missing( name, *args )
    puts "There is no method '##{name}' defined on #{self.class}, you dummy!"
  end
end

[ 1, 2, 3 ][ 3 ] > 2 
#=> There is no method '#>' defined on NilClass, you dummy!
  

为什么它不像NullPointerException

那样

Ruby中没有这样的例外。检查Ruby的Exception类。

答案 1 :(得分:0)

必须将其转换为整数变量才能执行opercio:

  • @state_turns [state.id] .to_i&gt; 0
  • state_a = state.auto_removal_timing.to_i + 1
相关问题