Rails中的受保护和私有方法

jrd*_*oko 81 ruby visibility private ruby-on-rails protected

Ruby(公共,受保护和私有方法)中的方法可见性已经在像这篇博客文章这样的地方得到了很好的解释.但是在Ruby on Rails中,由于框架的设置方式,它似乎与常规Ruby应用程序略有不同.那么,在Rails模型,控制器,帮助器,测试等中,何时/不适合使用受保护或私有方法?

编辑:感谢您的答案到目前为止.我理解Ruby中的protected和private的概念,但我正在寻找更多关于在Rails应用程序的各个部分(模型,控制器,帮助程序,测试)的上下文中使用这些类型的可见性的典型方式的解释.例如,公共控制器方法是操作方法,应用程序控制器中的受保护方法用于需要由多个控制器访问的"辅助方法"等.

ave*_*ell 105

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

这与其他面向对象语言中的做法相同.

对于控制器和测试,只需按照您的要求进行操作.控制器和测试类都只是实例化并由框架调用(是的,我知道你理论上可以从视图中获取控制器,但如果你这样做,那么有些事情很奇怪).由于没有人会直接创造这些东西,所以没有什么可以"保护"的.

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

对于帮助者,如果方法受到保护或私有,它将没有区别,因为它们总是被"直接"调用.

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

  • 如今,我仅使用私有。保护和私有在大多数地方可以互换使用;但是受到保护会带来一种我在现实世界中从未需要的奇怪行为。 (2认同)
  • 我倾向于只使用私人.这也遵循某些指导原则,例如[Thoughtbot的"在定义控制器方法时使用私有而不是受保护."](https://github.com/thoughtbot/guides/blob/98eede4e2d93d76b0e9e5bdedb6899985de6d574/style/README.md#L196) (2认同)

Ena*_*ane 65

如果除了self使用方法之外不需要其他人,则使用私有方法.如果你想要只能self and is_a?(self)调用的东西,你可以使用受保护的方法.

如果您使用"虚拟"初始化方法,则可以很好地使用受保护的方法.

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
Run Code Online (Sandbox Code Playgroud)

@foo将有不同的值.并且Derived实例不会有@baz

更新:自从我写这篇文章以来,Ruby 2.0中的一些内容发生了变化.Aaron Patterson写了一篇很棒的文章http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html

  • 注意到这里!这是与其他语言的重要区别:私有方法*也可用于子类.private和protected的唯一区别是您可以使用"self.set_defaults"调用受保护的方法,而私有方法只能被称为"set_defaults". (16认同)
  • 喜欢你怎么说'self and is_a?(self)`.我总是将受保护的方法解释为可在儿童课程中使用. (9认同)
  • 注意他的问题的编辑时间戳.将来我将定义一个私有方法来更新我的答案,因为他们改变了他们的问题:) (5认同)

nun*_*nia 10

受保护和私密之间的区别是微妙的.如果方法受到保护,则可以由定义类或其子类的任何实例调用它.如果一个方法是私有的,那么它只能在调用对象的上下文中调用---它永远不可能直接访问另一个对象实例的私有方法,即使该对象与调用者属于同一个类.对于受保护的方法,可以从同一类(或子类)的对象访问它们.

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

  • 在最后一种情况下"应用程序控制器中的受保护方法可以由其他控制器使用"这是因为其他控制器(通常)*从*ApplicationController继承,因此它们实际上拥有所有这些方法本身.他们没有从application_controller访问它们:这不会被实例化.它纯粹用作继承的父级. (3认同)
  • 谢谢你的链接.但是我想知道更多关于这些如何在Ruby on Rails中工作(公共控制器方法被视为操作方法,应用程序控制器中的受保护方法可以被其他控制器使用等) (2认同)