Rails Rails 3 与 Rails 4 中 try 方法的不同

michael_roshen · 2014年11月19日 · 最后由 vary 回复于 2014年12月11日 · 8647 次阅读
本帖已被管理员设置为精华贴

Rails 最新版本中,在使用 try 调用私有方法的时候,有了一些差异

class User
  include Mongoid::Document

  private
  def say
    puts "hello, world"
  end
end

Rails 3:

u = User.new
u.try(:say)
==> hello, world

rails4:

u = User.new
u.try(:say)
==> nil

测试,Rails 3 中对象可以直接使用 try 调用私有方法,但是 Rails 4 中则不可以 我们来看看源代码

Rails 3.1 稳定版

def try(*a, &b)
  if a.empty? && block_given?
    yield self
  else
    __send__(*a, &b)
  end
end

Rails 4.1 稳定版

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 则只能调用公有方法

我的博客:http://michael-roshen.iteye.com/blog/2158053

学习了~ 😄

了解了,thanks.

喜欢这类小文...

牛!简洁清晰易懂,赞!

我能说这个是 Rails 的 bug 改进吗?

有这个必要吗? 为什么总是想尽办法调用私有方法,它的目的就是不让别人调用的

#8 楼 @string2020 rails3 应该是有漏洞,所以在 rails4 中改进的,我也是在升级 rails4 的时候发现老代码有这样用的,写出来分享一下,并不主张调用私有方法

第一反应还以为是之前 ruby 里面那个对非 nil 对象调用 try 仍然会报找不到方法的帖子呢😄

了解了。。。

加深了对 try 的认识了!!

#13 楼 @nagae_memooff 哟,天津老乡,哈哈

@rainchen 没错,调用私有方法的行为就应该报错。

#8 楼 @string2020 如果不让别人调用,那干嘛还有 send 方法?

#18 楼 @lhy20062008 rails3 是公有和私有方法都能调,但是调用私有方法是不合适的,所以 rails4 改成只能调用公有方法,使用 public_send 了

#11 楼 @rainchen 看完帖子后再看看 11 楼,涨姿势了。

多了个坑

#18 楼 @lhy20062008 send 来自语言的核心。用来实现语言本身而不是用来破坏封装的。

#11 楼 @rainchen 本来意图为了防止user 是nil时不报异常,应该是防止 user 是 nil 时报异常吧。

赞一个 rails3 的 bug 在 rails 4 中修复了,私有方法 和 公有方法 划分接线

#11 楼 @rainchen 此楼一句话描述清楚了问题,赞。

还真没发现,学习了

恩,还没发现,学习了

michael_roshen Rails 4 升级第二弹 提及了此话题。 04月03日 10:57
需要 登录 后方可回复, 如果你还没有账号请 注册新账号