eli*_*lon 5 ruby ruby-on-rails activesupport
如果您尝试nil在Ruby中调用对象上的方法,则会NoMethodError出现以下消息的异常:
"undefined method ‘...’ for nil:NilClass"
Run Code Online (Sandbox Code Playgroud)
但是,try在Rails中有一个方法,nil如果它被发送到一个nil对象,它就会返回:
require 'rubygems'
require 'active_support/all'
nil.try(:nonexisting_method) # no NoMethodError exception anymore
Run Code Online (Sandbox Code Playgroud)
那么try内部如何工作以防止该异常?
ActiveSupport 4.0.0定义了两种try方法:一种是用于Object实例:
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
Run Code Online (Sandbox Code Playgroud)
另一个是实例(对象):NilClassnil
class NilClass
def try(*args)
nil
end
end
Run Code Online (Sandbox Code Playgroud)
现在,假设我们有一个Object实例(不包括nil,它实际上继承自Object,就像 Ruby 中的其他所有内容一样),定义一个返回 的方法nil:
class Test
def returns_nil
nil
end
end
Run Code Online (Sandbox Code Playgroud)
因此,运行Test.new.try(:returns_nil)or被调用Test.new.not_existing_method,Object#try它检查公共方法是否存在(the respond_to?);如果确实如此,则调用该方法(public_send),否则返回nil(没有其他行)。
如果我们调用try这些返回方法中的另一个nil:
Test.new.try(:returns_nil).try(:any_other_method)
Test.new.try(:not_existing_method).try(:any_other_method)
Run Code Online (Sandbox Code Playgroud)
我们调用NilClass#try,即nil#try,它会忽略所有内容并返回nil。try因此,在实例上调用任何其他nil实例并返回nil。