Méthodes protégées et privées dans Rails

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 ce billet de blog . Mais dans Ruby on Rails, il semble légèrement différent de ce qu’il serait dans une application Ruby classique en raison de la configuration du framework. Donc, dans les modèles Rails, les contrôleurs, les helpers, les tests, etc., quand est-il / convient-il d’utiliser des méthodes protégées ou privées?

Edit : Merci pour les réponses jusqu’ici. Je comprends le concept de protégé et privé dans Ruby, mais je cherche davantage une explication de la manière typique dont ces types de visibilité sont utilisés dans le contexte des différentes parties 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 sont l’interface publique de la classe. Les méthodes publiques sont destinées à être utilisées par d’autres objects, 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 object.

Pour les contrôleurs et les tests, faites comme vous voulez. Les deux classes de contrôleur et 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 est étrange de toute façon ). Puisque personne ne créera jamais ces choses directement, il n’y a rien à “protéger” contre.

Addendum / Correction: Pour les contrôleurs, vous devez marquer les méthodes “helper” comme privées protégées , et seules les actions elles-mêmes doivent être publiques. L’infrastructure ne routera jamais les appels HTTP entrants vers des actions / méthodes qui ne sont pas publiques, de sorte que vos méthodes d’assistance doivent être protégées de cette manière.

Pour les assistants, cela ne fera aucune différence si une méthode est protégée ou privée, car ils sont toujours appelés “directement”.

Vous pouvez marquer des éléments protégés dans tous ces cas si cela facilite les choses, bien sûr.

Vous utilisez une méthode privée si vous souhaitez que personne d’autre que self n’utilise une méthode. Vous utilisez une méthode protégée si vous voulez quelque chose que seuls self and is_a?(self) peuvent 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 toute instance de la classe ou de ses sous-classes. Si une méthode est privée, elle peut être appelée uniquement dans le contexte de l’object appelant — il n’est jamais possible d’accéder directement aux méthodes privées d’une instance d’un autre object, même si l’object est de la même classe que l’appelant. Pour les méthodes protégées, elles sont accessibles à partir d’objects de la même classe (ou enfants).

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

Vous semblez avoir une bonne idée de la sémantique de la visibilité de classe (public / protected / private) appliquée aux méthodes. Tout ce que je peux offrir, c’est un aperçu rapide de la façon dont je l’implémente dans mes applications Rails.

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 veux utiliser dans tous les modèles 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 catch-all tel que /:controller/:action/:id ou s’il est désactivé (valeur par défaut dans Rails 3), seules les méthodes avec des routes 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 modèle Liquid, car vous pouvez fournir une interface publique plutôt que d’utiliser les filtres et les balises Liquid.