Ruby on rails 如果对象::try';它被发送到一个零对象?
如果尝试在Ruby中调用Ruby on rails 如果对象::try';它被发送到一个零对象?,ruby-on-rails,ruby,activesupport,Ruby On Rails,Ruby,Activesupport,如果尝试在Ruby中调用nil对象上的方法,则会出现NoMethodError异常,并显示以下消息: "undefined method ‘...’ for nil:NilClass" 但是,Rails中有一个方法,如果发送到nil对象,它只返回nil: require 'rubygems' require 'active_support/all' nil.try(:nonexisting_method) # no NoMethodError exception anymore 那么try
nil
对象上的方法,则会出现NoMethodError
异常,并显示以下消息:
"undefined method ‘...’ for nil:NilClass"
但是,Rails中有一个方法,如果发送到nil
对象,它只返回nil
:
require 'rubygems'
require 'active_support/all'
nil.try(:nonexisting_method) # no NoMethodError exception anymore
那么try
如何在内部工作以防止这种异常呢?来自Rails(3.2):
方法
try
只是为nil
对象单独实现,因此它总是返回nil
,即使您尝试调用的方法是为nil
对象实现的 它忽略参数,只返回nil
。以下是:
请注意,此实现始终返回nil
,即使nil
响应该方法:
nil.try(:to_i) # => nil, rather than 0
与Ruby中的所有其他对象一样,
nil
有一个类(),它有方法。例如,nil?
在NilClass
上定义为返回true,这就是为什么nil.nil?
不返回NoMethodError
的原因
ruby中的每个类都可以打开(使用新方法更新)。Rails打开
NilClass
添加try
方法并让它返回nil
(这也是为什么即使链中的一个步骤返回nil
,也可以链接try
,因为后续的nil
也会响应try
).ActiveSupport 4.0.0定义了两种try
方法:用于对象
实例:
class Object
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
end
用于NilClass
实例(nil
对象):
现在,假设我们有一个对象
实例(不包括nil
,它实际上继承了对象
,就像Ruby中的其他东西一样),定义了一个返回nil
的方法:
class Test
def returns_nil
nil
end
end
因此,运行Test.new.try(:返回_nil)
或Test.new.not\u existing\u方法
,将调用对象#try
,它将检查是否存在公共方法(响应?
);如果它这样做,它将调用该方法(public\u send),否则它将返回nil
(没有其他行)
如果我们调用另一个方法,请尝试这些返回的nil
方法中的一种:
Test.new.try(:returns_nil).try(:any_other_method)
Test.new.try(:not_existing_method).try(:any_other_method)
我们将调用NilClass#try
,它是nil#try
,它将忽略所有内容并返回nil
。因此,任何其他try
都将在nil
实例上调用,并返回nil
“如果尝试在nil
对象上调用方法,则会出现异常”=>错误。“如果您试图在nil
上为NilClass
调用未定义的方法,则会出现异常”=>正确。
class NilClass
def try(*args)
nil
end
end
class Test
def returns_nil
nil
end
end
Test.new.try(:returns_nil).try(:any_other_method)
Test.new.try(:not_existing_method).try(:any_other_method)