Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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?

like image 839
Netorica Avatar asked Nov 03 '13 09:11

Netorica


People also ask

What is an error NoMethodError undefined method for nil NilClass?

Explained. This is a common Ruby error which indicates that the method or attribute for an object you are trying to call on an object has not been defined. For example, the String class in Ruby has the method size (which is synonymous with length , so I can write...

What does undefined method for nil NilClass mean?

The Undefined method for nil:NILClass occurs when you attempt to use a formula on a blank datapill. This indicates that the datapill was not provided any value at runtime.

What does undefined method mean?

The undefined method is also called the NoMethodError exception, and it's the most common error within projects, according to The 2022 Airbrake Error Data Report. It occurs when a receiver (an object) receives a method that does not exist.

What is NilClass?

NilClass is a built-in class provided by Ruby. This class is not instantiable. irb> NilClass.new. NoMethodError (undefined method `new' for NilClass:Class) When a message is sent to nil , a hard-coded C-level “class” called rb_cNilClass — which corresponds to the NilClass in Ruby — is used as receiver of the message.


2 Answers

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.

like image 200
Arup Rakshit Avatar answered Oct 05 '22 01:10

Arup Rakshit


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
like image 41
Osmar Valero Avatar answered Oct 05 '22 02:10

Osmar Valero