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

标签 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>

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

最佳答案

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

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

what is the cause of the error?

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

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 异常。为了演示,让我们通过插入自定义消息在 Object 中定义 #method_missing 方法,该消息将代替 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

Ruby 中没有这样的异常(exception)。检查 Ruby 的 Exception类。

关于ruby - 未定义方法 '>' 为 nil :NilClass <NoMethodError>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19751427/

相关文章:

C++三元运算符混淆

ruby - 从 Ruby 发布时如何避免对 JSON 进行 uri 编码?

python - Ruby 系统调用不观察 python 脚本的路径

ruby-on-rails - rails 4.1 : Can't cast Hash to string

java - 计算类(class)平均分

php - 具有多个参数的一种方法还是具有一个参数的多种方法?

java - 不能从具有方法和变量的静态上下文中引用非静态方法

Java如何查看String中是否有整数

ruby-on-rails - Rails 教程 - 命名路由

lua - [函数类 :me() end] equal to [function class. me(self) end] 在 lua 中吗?