好的,我有下面的代码
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/