Rails 最新版本中,在使用 try 调用私有方法的时候,有了一些差异
class User
include Mongoid::Document
private
def say
puts "hello, world"
end
end
u = User.new
u.try(:say)
==> hello, world
rails4:
u = User.new
u.try(:say)
==> nil
测试,Rails 3 中对象可以直接使用 try 调用私有方法,但是 Rails 4 中则不可以 我们来看看源代码
def try(*a, &b)
if a.empty? && block_given?
yield self
else
__send__(*a, &b)
end
end
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
主要差异在于 send 和 public_send, 如果你是个老手,肯定知道怎么回事了 send 是 Ruby 的内核方法,可以调用任意方法 public_send 则只能调用公有方法
#8 楼 @string2020 rails3 应该是有漏洞,所以在 rails4 中改进的,我也是在升级 rails4 的时候发现老代码有这样用的,写出来分享一下,并不主张调用私有方法
是 bugfix, 因为 user.try(:say) 的本来意图为了防止 user 是 nil 时不报异常。但如果你本来的意图是调用一个私有方法如 user.secert,应该抛异常,所以 user.try(:secert) 也不应该返回有效值才合理。
#18 楼 @lhy20062008 rails3 是公有和私有方法都能调,但是调用私有方法是不合适的,所以 rails4 改成只能调用公有方法,使用 public_send 了