nil的未定义方法’>’:NilClass
好的,我有以下代码
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
错误的原因是什么? 怎么来>
被认为是一种方法,但它是一个逻辑运算符?
怎么来>被认为是一种方法,但它是一个逻辑运算符?
这没有问题。 在Ruby中,当你编写一个像1 + 2
这样的表达式时,在内部它被理解为1.+( 2 )
:在接收器1
上调用方法#+
,其中2
作为单个参数。 理解相同的另一种方法是,您将消息[ :+, 2 ]
发送到对象1
。
错误的原因是什么?
现在在你的情况下, @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
exception是合法错误。 通过引发此错误,Ruby会保护您:它会提前告诉您@state_turns[ state.id ]
不是您认为的那样。 这样,您可以更早地纠正错误,成为更有效的程序员。 此外,可以使用begin ... rescue ... end
语句begin ... rescue ... end
Rubyexception。 Rubyexception通常是非常友好和有用的对象,您应该学习如何在软件项目中定义自定义exception。
为了进一步扩展这个讨论,让我们看看你的错误来自哪里。 当你编写一个像nil > 10
的表达式,实际上是nil.>( 10 )
,Ruby开始在nil
的查找链中搜索#>
方法。 您可以通过键入以下内容来查看查找链:
nil.singleton_class.ancestors #=> [NilClass, Object, Kernel, BasicObject]
该方法将在祖先链的每个模块中进行搜索:首先,Ruby将检查是否在NilClass
上定义了#>
,然后在Object
上定义了Kernel
,然后是Kernel
,最后是BasicObject
。 如果在其中任何一个中找不到#>
,Ruby将继续尝试method_missing
方法,再次按顺序查找链的所有模块。 如果even method_missing
不处理:>
消息,则会引发NoMethodError
exception。 为了演示,让我们通过插入一个自定义消息来定义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!
为什么它不像NullPointerException那样说
Ruby中没有这样的例外。 检查Ruby的Exception
类。
必须将其转换为整数变量才能执行opercio:
- @state_turns [state.id] .to_i> 0
- state_a = state.auto_removal_timing.to_i + 1