La visibilité des méthodes dans Ruby (méthodes publiques, protégées et privées) a été bien expliquée dans des endroits tels que cet article de blog . Mais dans Ruby sur Rails, il semble légèrement différent de ce qu'il serait dans une application normale Ruby en raison de la façon dont le cadre est configuré. Ainsi, dans Rails modèles, contrôleurs, aides, tests, etc., quand est-il/ne convient-il pas d'utiliser des méthodes protégées ou privées?
Edit : Merci pour les réponses jusqu'à présent. Je comprends le concept de protected et private dans Ruby, mais je cherche plus à expliquer la manière typique dont ces types de visibilité sont utilisés dans le contexte des différentes pièces d’une application Rails (modèles, contrôleurs, aides, tests). Par exemple, les méthodes de contrôleur public sont des méthodes d'action. Les méthodes protégées dans le contrôleur d'application sont utilisées pour les "méthodes d'assistance" auxquelles plusieurs contrôleurs doivent accéder, etc.
Pour les modèles, l'idée est que les méthodes publiques constituent l'interface publique de la classe. Les méthodes publiques sont destinées à être utilisées par d'autres objets, tandis que les méthodes protégées/privées doivent être masquées de l'extérieur.
C'est la même pratique que dans d'autres langages orientés objet.
Pour contrôleurs et des tests, faites comme bon vous semble. Contrôleur et les classes de test sont seulement instanciées et appelées par le framework (oui, je sais que vous pouvez théoriquement obtenir le contrôleur de la vue, mais si vous faites cela, quelque chose d'étrange quand même). Puisque personne ne créera jamais ces choses directement, il n'y a rien contre quoi "protéger".
Addendum/Correction: Pour les contrôleurs, vous devez marquer les méthodes "helper" comme protégé privé, et seules les actions elles-mêmes doivent être publiques. La structure ne routera jamais les appels HTTP entrants vers des actions/méthodes qui ne sont pas publiques. Par conséquent, vos méthodes d'assistance doivent être protégées de cette manière.
Pour les assistants, le fait qu'une méthode soit protégée ou privée ne fera aucune différence, car ils sont toujours appelés "directement".
Vous pouvez marquer les éléments comme protégés dans tous ces cas si cela vous facilite la compréhension, bien sûr.
Vous utilisez une méthode privée si vous ne voulez personne d'autre que self
utiliser une méthode. Vous utilisez une méthode protégée si vous voulez que quelque chose que self and is_a?(self)
s puisse appeler.
Une bonne utilisation de protected pourrait être si vous aviez une méthode d'initialisation "virtuelle".
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 aura des valeurs différentes. et les instances dérivées n'auront pas @baz
Mise à jour: Depuis que j'ai écrit ceci, certaines choses ont changé dans Ruby 2.0+. Aaron Patterson a une excellente rédaction http://tenderlovemaking.com/2012/09/07/protected -methods-and-Ruby-2-0.html
La différence entre protégé et privé est subtile. Si une méthode est protégée, elle peut être appelée par n’importe quelle instance de la classe de définition ou de ses sous-classes. Si une méthode est privée, elle ne peut être appelée que dans le contexte de l'objet appelant. Il n'est jamais possible d'accéder directement aux méthodes privées d'une autre instance d'objet, même si l'objet appartient à la même classe que l'appelant. Pour les méthodes protégées, elles sont accessibles à partir d'objets de la même classe (ou des enfants).
http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility
Vous semblez avoir une bonne idée de la sémantique de la visibilité des classes (public/protected/private) appliquée aux méthodes. Tout ce que je peux offrir est un bref aperçu de la façon dont je l’implémente dans mes Rails applications.
J'implémente des méthodes protégées dans le contrôleur d'application de base afin qu'elles puissent être appelées par n'importe quel contrôleur via des filtres (par exemple, before_filter: method_foo). De la même manière, je définis des méthodes protégées pour les modèles que je souhaite utiliser dans chacun d'eux dans un modèle de base dont ils héritent tous.
Bien que les actions doivent être des méthodes publiques d'un contrôleur, toutes les méthodes publiques ne sont pas nécessairement des actions. Vous pouvez utiliser hide_action
si vous utilisez un itinéraire fourre-tout comme /:controller/:action/:id
ou s'il est désactivé (la valeur par défaut est Rails 3), seules les méthodes comportant des itinéraires explicites seront appelées.
Cela peut être utile si vous transmettez l'instance de contrôleur à une autre bibliothèque, telle que le moteur de gabarit Liquid, car vous pouvez fournir une interface publique plutôt que de devoir utiliser l'envoi de vos filtres et balises Liquid.