Rails中受保护和私有的方法

Ruby中的方法可见性(公共,受保护和私有方法)已经在这篇博文中得到很好的解释。 但是在Ruby on Rails中,由于框架的设置方式,它和普通的Ruby应用程序看起来略有不同。 那么,在Rails模型,控制器,帮助器,testing等方面,何时/不适合使用受保护或私有方法?

编辑 :感谢迄今为止的答案。 我理解Ruby中的protected和private的概念,但是我更多地了解这些types的可见性在Rails应用程序(模型,控制器,帮助程序,testing)的各个环境中使用的典型方式。 。 例如,公共控制器方法是操作方法,应用程序控制器中的受保护方法用于需要由多个控制器访问的“辅助方法”。

对于模型,这个想法是公共方法是类的公共接口。 公共方法旨在被其他对象使用,而受保护/私有方法将从外部隐藏。

这在其他面向对象的语言中也是一样的。

对于控制器和testing,只要你喜欢。 控制器和testing类都只是实例化和框架调用( 是的,我知道你理论上可以从视图中获得控制器,但是如果你这样做,反正有些东西是奇怪的 )。 由于没有人会直接创造这些东西,所以没有什么可以“保护”。

附录/更正:对于控制器,您应该将“帮手”方法标记为保护私有方法,只有操作本身应该公开。 框架永远不会将任何传入的HTTP调用路由到非公开的动作/方法,因此应该以这种方式保护你的帮助器方法。

对于帮助者来说,如果某个方法是受保护的或私有的,那么它们就没有区别,因为它们总是被称为“直接”的。

当然,如果让事情变得更容易理解,你可以在所有这些情况下标记受保护的东西。

如果您不需要其他人,但使用self方法,则可以使用私有方法。 如果你只想要self and is_a?(self) s可以调用,你使用受保护的方法。

如果你有一个“虚拟的”初始化方法,那么保护的好处可能就是如此。

 class Base def initialize() set_defaults() #other stuff end protected def set_defaults() # defaults for this type @foo = 7 calculate_and_set_baz() end private def calculate_and_set_baz() @baz = "Something that only base classes have like a file handle or resource" end end class Derived < Base protected def set_defaults() @foo = 13 end end 

@foo将会有不同的值。 Derived实例不会有@baz

更新:由于我写了这个,有些事情已经改变了Ruby 2.0+亚伦帕特森有一个很好的写作http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html

保护和私人之间的区别是微妙的。 如果一个方法被保护,它可以被定义的类或其子类的任何实例调用。 如果一个方法是私有的,那么它只能在调用对象的上下文中调用 – 即使对象与调用者具有相同的类,也不可能直接访问另一个对象实例的私有方法。 对于受保护的方法,它们可以从同一类(或孩子)的对象访问。

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility

您似乎对应用于方法的类可见性(public / protected / private)的语义有了一个好的概念。 我所能提供的只是我在Rails应用程序中实现它的一个简要概述。

我在基础应用程序控制器中实现受保护的方法,以便任何控制器都可以通过filter调用它们(例如before_filter:method_foo)。 以类似的方式,我定义了模型的受保护的方法,我想在它们全部inheritance的基础模型中使用它们。

尽pipe行动需要成为控制者的公共方法,但并非所有的公共方法都必然是行动。 如果使用/:controller/:action/:id这样的catch-all路由,或者它被禁用(Rails 3中的默认路由),那么可以使用hide_action ,那么只有具有显式路由的方法才会被调用。

如果您将控制器实例传递给Liquid模板引擎等其他库,则可以提供公共接口,而不必在Liquidfilter和标签中使用send。