为什么 > 被认为是一种方法,但它是一个逻辑运算符?
没有问题。在 Ruby 中,当您编写类似 的表达式时1 + 2
,在内部它被理解为:在接收器上1.+( 2 )
调用方法,并作为单个参数。另一种理解方式是,您正在将消息发送到 object 。#+
1
2
[ :+, 2 ]
1
错误的原因是什么?
现在在你的情况下,由于某种原因@state_turns[ state.id ]
返回nil
。所以表达式@state_turns[state.id] > 0
变成nil > 0
了 ,正如我之前所说的,它被理解为调用#>
方法 on nil
。但是您可以检查NilClass
所属nil
的 没有#>
在其上定义实例方法:
NilClass.instance_methods.include? :> # => false
nil.respond_to? :> # => false
因此,该NoMethodError
异常是一个合法错误。通过引发这个错误,Ruby 保护了你:它很早就告诉你你@state_turns[ state.id ]
的不是你想象的那样。这样,您可以更早地纠正错误,并成为更高效的程序员。此外,Ruby 异常可以通过begin ... rescue ... end
语句来挽救。Ruby 异常通常是非常友好和有用的对象,您应该学习如何在软件项目中定义自定义异常。
为了进一步扩展这个讨论,让我们看看你的错误来自哪里。当你写一个类似的表达式nil > 10
时,实际上是nil.>( 10 )
Ruby 开始#>
在nil
. 您可以通过键入以下内容查看查找链:
nil.singleton_class.ancestors #=> [NilClass, Object, Kernel, BasicObject]
该方法将在祖先链的每个模块中进行搜索:首先,Ruby 会检查是否#>
定义了 on NilClass
,然后 on 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
类。