J'ai une question en deux parties
Meilleur entrainement
- J'ai un algorithme qui effectue une opération sur une structure de données à l'aide de l'interface publique
- Il s'agit actuellement d'un module avec de nombreuses méthodes statiques, toutes privées à l'exception de la méthode d'interface publique unique.
- Il y a une variable d'instance qui doit être partagée entre toutes les méthodes.
Voici les options que je peux voir, quelle est la meilleure?:
- Module avec méthodes statiques ('module' en ruby)
- Classe avec méthodes statiques
- Module Mixin pour inclusion dans la structure de données
- Refactoriser la partie de l'algorithme qui modifie cette structure de données (très petite) et en faire un mixin qui appelle les méthodes statiques du module d'algorithme
Partie technique
Existe-t-il un moyen de créer une méthode Module privée ?
module Thing
def self.pub; puts "Public method"; end
private
def self.priv; puts "Private method"; end
end
Le private
dedans ne semble pas avoir d'effet , je peux toujours appeler Thing.priv
sans problème.
ruby
private-methods
access-specifier
Daniel Beardsley
la source
la source
private
n'affecte que les méthodes d'instance, pas les méthodes de classe. utiliser à laprivate_class_method
place:module Thing; def self.pub; end; private_class_method :pub; end
Réponses:
Je pense que la meilleure façon (et surtout la façon dont les bibliothèques existantes sont écrites) pour ce faire est de créer une classe dans le module qui traite toute la logique, et le module fournit simplement une méthode pratique, par exemple
la source
perform
n'est pas la méthode qui est censée être privée ici, la méthode privée est la méthode privée de laTranslator
classe (l'exemple de @ ucron n'en a pas, ce qui est très malheureux).GTranslate.translate
est seulement une méthode pratique pourGTranslate::Translator#perform
, il n'y a pas de réel gain qui la dissimule, si c'était possible.self.translate
déclare une méthode de classe / module.GTranslate::Translator.new.perform(text)
- alambiqué, mais pas privé!Il y a aussi
Module.private_class_method
, qui exprime sans doute plus d'intention.Pour le code de la question:
Ruby 2.1 ou plus récent:
la source
private
?la source
include Writer
option!Vous pouvez utiliser la méthode "inclus" pour faire des choses fantaisistes quand un module est mélangé. Cela fait ce que vous voulez, je pense:
la source
included do |base| [...] end
au lieu de defMalheureusement,
private
ne s'applique qu'aux méthodes d'instance. La manière générale d'obtenir des méthodes "statiques" privées dans une classe est de faire quelque chose comme:Certes, je n'ai pas joué avec cela dans les modules.
la source
.foo
une méthode de classe privée: "private; def self.foo ()"private
etprivate_class_method
appartiennent àModule
notClass
. Ce code fonctionne d'ailleurs et c'est l'alternative à l'utilisationprivate_class_method
.Une belle façon est comme ça
la source
Qu'en est-il du stockage de méthodes en tant que lambdas dans des variables / constantes de classe?
Pour le test:
UPD: une énorme mise à jour de ce code après 6 ans montre un moyen plus propre de déclarer une méthode privée
d
Ici, nous voyons que:
1)
@@L
ne peut pas être accessible de l'extérieur mais est accessible de presque partout2)
class << self ; private ; def
rend la méthoded
inaccessible de l'extérieur et de l'intérieur avecself.
mais pas sans - c'est bizarre3)
private ; self.
etprivate ; class << self
ne rend pas les méthodes privées - elles sont accessibles à la fois Avec et sansself.
la source
Proc
, tandis que les méthodes sont de typeMethod
.Créer un module ou un cours privé
Les constantes ne sont jamais privées. Cependant, il est possible de créer un module ou une classe sans l'affecter à une constante.
Donc, une alternative à
:private_class_method
est de créer un module ou une classe privée et de définir des méthodes publiques dessus.Usage:
Consultez la documentation pour Module.new et Class.new .
la source
.self
dans les définitions de méthode, de l'inclure dans une autre classe et de les utiliser comme instance_methods de la classe d'inclusion. Savez-vous s'il existe un moyen de le faire fonctionner?Cette méthode n'autorise pas le partage de données avec les méthodes privées, sauf si vous transmettez explicitement les données par des paramètres de méthode.
la source