ruby 未定义的方法 '>' 为 nil:NilClass <NoMethodError>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19751427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 06:16:55  来源:igfitidea点击:

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

rubymethodsoperator-keyword

提问by Netorica

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?

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

回答by Arup Rakshit

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 1with 2as a single argument. Another way to understand the same is, that you are sending the message [ :+, 2 ]to the object 1.

没有问题。在Ruby中,当你写等的表达1 + 2,它在内部被理解为1.+( 2 ):调用方法#+在接收器上12作为单个参数。另一种理解相同的方法是,您将消息发送[ :+, 2 ]到 object 1

what is the cause of the error?

错误的原因是什么?

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

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

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

The NoMethodErrorexception 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 ... endstatement. Ruby exceptions are generally very friendly and useful objects, and you should learn how to define your custom exceptions in your software projects.

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

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 > 10,实际上nil.>( 10 ),Ruby 开始#>在 的查找链中搜索方法nil。您可以通过键入以下内容查看查找链:

    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_missingmethods, again in order on all the modules of the lookup chain. If even method_missingdoes not handle the :>message, NoMethodErrorexception will be raised. To demonstrate, let's define #method_missingmethod in Objectby inserting a custom message, that will appear instead of NoMethodError:

该方法将在祖先链的每个模块中进行搜索:首先,Ruby 会检查是否#>定义了 on NilClass,然后是 on Object,然后是Kernel,最后是BasicObject。如果#>没有在其中任何一个中找到,Ruby 将继续尝试method_missing方法,再次在查找链的所有模块上按顺序进行。如果 evenmethod_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!

Why doesn't it says like NullPointerException

为什么它不像 NullPointerException 那样说

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

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

回答by Osmar Valero

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
  • @state_turns [state.id] .to_i > 0
  • state_a = state.auto_removal_timing.to_i + 1