好的我有以下代码
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>
错误的原因是什么? 如何将>
视为一种方法,但它是一个逻辑运算符?
答案 0 :(得分:51)
怎么来&gt;被认为是一种方法,但它是一个逻辑运算符?
没有问题。在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
。如果在其中任何一个中找不到#>
,Ruby将继续尝试method_missing
方法,再次按顺序查找链的所有模块。如果即使method_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!
为什么它不像NullPointerException
那样
Ruby中没有这样的例外。检查Ruby的Exception
类。
答案 1 :(得分:0)
必须将其转换为整数变量才能执行opercio: