好的,我有以下代码
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>
错误的原因是什么? 为什么将
>
视为一种方法,但它是逻辑运算符? 最佳答案
没问题。在Ruby中,当您编写类似于1 + 2
的表达式时,在内部将其理解为1.+( 2 )
:在接收方#+
上调用方法1
,并将2
作为单个参数。另一种理解方法是将消息[ :+, 2 ]
发送到对象1
。
现在就您而言,@state_turns[ state.id ]
由于某种原因返回nil
。因此,表达式@state_turns[state.id] > 0
变为nil > 0
,正如我之前所说的,可以理解为在#>
上调用nil
方法。但是您可以检查NilClass
所属的nil
上没有定义实例方法#>
:
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
上定义了,最后是#>
。如果未在其中找到method_missing
,则Ruby将继续尝试method_missing
方法,以在查找链的所有模块上再次按顺序进行。如果即使:>
也不处理NoMethodError
消息,也会引发#method_missing
异常。为了演示,让我们通过插入自定义消息而不是Object
来在NoMethodError
中定义Exception
方法: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!
Ruby中没有这样的异常(exception)。检查Ruby的 ojit_code 类。
关于ruby - 未定义的方法 '>'为nil:NilClass <NoMethodError>,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19751427/