ruby-on-rails ruby visibility private protected

ruby on rails - Métodos protegidos y privados en Rails



ruby-on-rails visibility (5)

La visibilidad del método en Ruby (métodos públicos, protegidos y privados) ha sido bien explicada en lugares como esta publicación de blog . Pero en Ruby on Rails parece algo diferente de lo que sería en una aplicación regular de Ruby debido a la forma en que está configurado el framework. Entonces, en los modelos de Rails, controladores, ayudantes, pruebas, etc., ¿cuándo / no es apropiado usar métodos protegidos o privados?

Editar : Gracias por las respuestas hasta ahora. Entiendo el concepto de privacidad y protección en Ruby, pero estoy buscando una explicación de la forma típica en que se usan esos tipos de visibilidad dentro del contexto de varias aplicaciones de Rails (modelos, controladores, ayudantes, pruebas). . Por ejemplo, los métodos de controlador público son métodos de acción, los métodos protegidos en el controlador de la aplicación se usan para "métodos auxiliares" a los que deben acceder múltiples controladores, etc.


La diferencia entre protegido y privado es sutil. Si un método está protegido, puede ser invocado por cualquier instancia de la clase definitoria o sus subclases. Si un método es privado, solo se puede llamar dentro del contexto del objeto que llama; nunca es posible acceder directamente a los métodos privados de otra instancia de objeto, incluso si el objeto es de la misma clase que el llamador. Para los métodos protegidos, son accesibles desde objetos de la misma clase (o niños).

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


Aunque las acciones deben ser métodos públicos de un controlador, no todos los métodos públicos son necesariamente acciones. Puedes usar hide_action si estás usando una ruta catch-all como /:controller/:action/:id o si está deshabilitada (por defecto en Rails 3) entonces solo se llamarán los métodos con rutas explícitas.

Esto puede ser útil si pasa la instancia del controlador a otra biblioteca, como el motor de plantilla de Liquid, ya que puede proporcionar una interfaz pública en lugar de tener que usar enviar los filtros y las etiquetas de Liquid.


Para los modelos, la idea es que los métodos públicos sean la interfaz pública de la clase. Los métodos públicos están destinados a ser utilizados por otros objetos, mientras que los métodos protegidos / privados deben ocultarse desde el exterior.

Esta es la misma práctica que en otros lenguajes orientados a objetos.

Para controladores y pruebas, solo haz lo que quieras. Tanto el controlador como las clases de prueba solo son instanciadas y llamadas por el framework ( sí, sé que teóricamente puedes obtener el controlador desde la vista, pero si lo haces, de todos modos algo es extraño ). Como nadie creará esas cosas directamente, no hay nada contra lo que "proteger".

Adición / corrección: para los controladores, debe marcar los métodos de "ayuda" como privados protegidos , y solo las acciones en sí deben ser públicas. El marco nunca enrutará ninguna llamada HTTP entrante a acciones / métodos que no sean públicos, por lo que sus métodos auxiliares deberían estar protegidos de esa manera.

Para los ayudantes no importará si un método está protegido o es privado, ya que siempre se llaman "directamente".

Puede marcar cosas protegidas en todos esos casos si le resulta más fácil comprenderlas, por supuesto.


Parece que tiene una buena idea de la semántica de la visibilidad de clase (pública / protegida / privada) aplicada a los métodos. Todo lo que puedo ofrecer es un resumen rápido de la forma en que lo implemento en mis aplicaciones de Rails.

Implemento métodos protegidos en el controlador de la aplicación base para que puedan ser llamados por cualquier controlador a través de filtros (por ejemplo, before_filter: method_foo). De manera similar, defino métodos protegidos para los modelos que quiero usar en todos ellos en un modelo base del que todos ellos heredan.


Usas un método privado si no quieres que nadie más que tú use un método. Utiliza un método protegido si desea algo solo self and is_a?(self) puede llamar a self_store.

Un buen uso de protegido podría ser si tuviera un método de inicialización "virtual".

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 tendrá diferentes valores. y las instancias Derivadas no tendrán @baz

Actualización: Desde que escribí esto, algunas cosas han cambiado en Ruby 2.0+ Aaron Patterson tiene una excelente redacción http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html