Undefined method '>' for nil:NilClass <NoMethodError>

99封情书 提交于 2019-12-18 10:41:40

问题


Ok I do have the following code

 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

now in the line of...

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

it says the error

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

what is the cause of the error? how come > is considered as a method but it is a logical operator?


回答1:


how come > is considered as a method but it is a logical operator?

There is no problem with that. In Ruby, when you write an expression like 1 + 2, internally it is understood as 1.+( 2 ): Calling method #+ on the receiver 1 with 2 as a single argument. Another way to understand the same is, that you are sending the message [ :+, 2 ] to the object 1.

what is the cause of the error?

Now in your case, @state_turns[ state.id ] returns nil for some reason. So the expression @state_turns[state.id] > 0 becomes nil > 0, which, as I said earlier, is understood as calling #> method on nil. But you can check that NilClass, to which nil belongs, has no instance method #> defined on it:

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

The NoMethodError exception is therefore a legitimate error. By raising this error, Ruby protects you: It tells you early that your @state_turns[ state.id ] is not what you assume it to be. That way, you can correct your errors earlier, and be a more efficient programmer. Also, Ruby exceptions can be rescued with begin ... rescue ... end statement. Ruby exceptions are generally very friendly and useful objects, and you should learn how to define your custom exceptions in your software projects.

To extend this discussion a bit more, let's look at from where your error is coming. When you write an expression like nil > 10, which is actually nil.>( 10 ), Ruby starts searching for #> method in the lookup chain of nil. You can see the lookup chain by typing:

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

The method will be searched in each module of the ancestor chain: First, Ruby will check whether #> is defined on NilClass, then on Object, then Kernel, and finally, BasicObject. If #> is not found in any of them, Ruby will continue by trying method_missing methods, again in order on all the modules of the lookup chain. If even method_missing does not handle the :> message, NoMethodError exception will be raised. To demonstrate, let's define #method_missing method in Object by inserting a custom message, that will appear instead of 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!

Why doesn't it says like NullPointerException

There is no such exception in Ruby. Check the Ruby's Exception class.




回答2:


It must be converted to integer variable to perform the opercio:

  • @state_turns [state.id] .to_i > 0
  • state_a = state.auto_removal_timing.to_i + 1


来源:https://stackoverflow.com/questions/19751427/undefined-method-for-nilnilclass-nomethoderror

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!