Je suis nouveau à Ruby (expérimenté avec Python, C++ et C). J'ai besoin de créer une classe qui ne doit être utilisée que par d'autres classes et méthodes dans un module. En Python, je l'appellerais simplement __classname. J'utiliserais un typedef vide en C++. Comment est-ce que je fais ceci dans Ruby (ou suis-je aboyant le mauvais arbre et ne pas le faire le "chemin de Ruby"?)Classe privée (méthode non classe) dans un module Ruby?
Répondre
Je n'ai pas vu un tel concept jusqu'ici dans Ruby, mais je suppose que vous pourriez simuler cela en créant une méthode privée qui retournerait une classe créée en tant que variable locale (souvenez-vous que dans Ruby, une classe est un objet comme n'importe quel autre, et peut être instanciée dans une méthode et retournée par elle). Par ailleurs, même les méthodes privées dans Ruby ne sont pas aussi privées que dans d'autres langues - vous pouvez toujours y accéder en utilisant la méthode send
. Mais faire cela implique que vous sachiez ce que vous faites.
La chose la plus importante à réaliser est qu'une classe n'a rien de spécial. C'est juste un objet. Par convention, les classes sont affectées à des constantes, mais rien ne dit qu'elles ont comme. Et comme les classes ne sont que des objets comme tout autre objet, vous les rendez privés de la même manière que tout autre objet privé.
Voici les possibilités que je peux penser, dans l'ordre de plus en plus privateness:
- Il suffit de les emboîter dans un espace de noms (module à savoir). Dans Ruby, on s'attend généralement à ce que tous les modules et classes d'une bibliothèque vivent dans un espace de noms portant le même nom que la bibliothèque (
my_awesome_library
→MyAwesomeLibrary
), mais en général, tout ce qui est imbriqué sous cet espace de noms est considéré comme privé. En fait, en plus deTest::Unit::TestCase
, je ne peux pas penser à un seul exemple d'un espace de noms profond à trois niveaux qui devrait être utilisé par le code client. - même que 1., mais nommez quelque chose d'évident, comme
MyAwesomeLibrary::Internal::FfiStruct
- même que 1. ou 2., et le marquer avec l'étiquette
:nodoc:
RDoc. - similaire à 3., mais utilisez un système de documentation plus moderne comme YARD, qui vous permet en fait de marquer explicitement les API privées.
- Utilisez une méthode au lieu d'une constante. Les méthodes peuvent être rendues privées. (Par souci de cohérence, vous pouvez faire en sorte que le nom de la méthode commence par une lettre majuscule, pour la faire ressembler à une constante.)
snake_case
est une convention. Ils sont toujours privés. Notez que les méthodes privées et les variables d'instance peuvent être accédées de manière triviale à l'aide de la réflexion.send
semble être plus répandu queinstance_variable_get
, ce qui explique pourquoi je considère que les variables d'instance ont un niveau de confidentialité plus élevé que les méthodes. En réalité, le seul moyen d'obtenir une confidentialité ou une encapsulation réelle est d'utiliser des variables et des fermetures locales. Notez toutefois que cela peut vous empêcher d'utiliser la syntaxe de définition de module, de classe ou de méthode de Ruby, car celles-ci créent de nouvelles étendues. Dans tous les cas où vous avez besoin d'accéder à la classe, vous devez utiliserModule.new
,Class.new
ouModule#define_method
.
Ex.:
module MyAwesomeLibrary
struct = Class.new(FFI::Struct) do
# ...
end
PublicInterface = Class.new do
define_method(:initialize) do |bar|
@foo = struct.new(bar)
end
end
end
Et oui, c'est la seule façon de parvenir à une véritable informations 100% cacher et l'encapsulation dans Ruby. Cependant, la manière normale de Ruby serait de documenter simplement le contenu comme étant privé (peut-être le pousser vers le bas d'un niveau de nom) et de faire confiance à vos collègues développeurs. Dans la communauté Ruby, ceci est parfois résumé sous le slogan Python "Nous sommes tous des adultes consentants".
"Nous sommes tous des adultes consentants" est un slogan de la communauté Python, pas de la communauté Ruby. –
Je ne voulais pas laisser entendre qu'il appartient à la communauté Ruby, mais seulement qu'il y est utilisé. Mais vous avez raison, le libellé est trompeur. Vingt ans d'apprentissage de l'anglais ne suffisent apparemment pas :-) –
Bonne réponse, merci! –
Prenant ces informations directement à partir this blog post, mais depuis Ruby 1.9.3, vous pouvez créer une classe privée dans un module en utilisant private_constant
:
class Person
class Secret
def to_s
"1234vW74X&"
end
end
private_constant :Secret
def show_secret
Secret.new.to_s
end
end
- 1. classe privée appelant une méthode de sa classe externe
- 2. Pouvez-vous ajouter une méthode de classe à la classe de module de base dans Ruby?
- 3. méthode non définie `call 'pour LiquidView: Classe
- 4. Classe privée dans un vecteur utilisé publiquement
- 5. Comment faire des constantes de classe privée dans Ruby
- 6. L'appel d'une méthode d'instance privée à partir d'une méthode de classe en Ruby
- 7. Que signifie "méthode de classe #" dans ruby?
- 8. Méthode générique dans une classe non générique?
- 9. PHP Méthode statique en utilisant une classe privée Fonctions/Variables
- 10. Méthode d'appel sur la classe incluse dans Ruby
- 11. 'Object' classe nommée dans Ruby
- 12. le module Ruby avec un appel de méthode statique de classe includer
- 13. Méthode pour dire si l'ancêtre est une classe ou un module en Ruby?
- 14. membres d'accès dans une classe privée
- 15. appels Ruby méthode déclarée dans le corps de la classe
- 16. ruby / datamapper: Méthodes de classe Refactor au module
- 17. @ Méthode privée asynchrone dans EJB
- 18. Créer une méthode dans une classe et l'utiliser dans Ruby
- 19. classe d'expéditeur à ruby?
- 20. Méthode reloadData non appelée d'une autre classe
- 21. Comment inclure un module dans une classe afin que le module remplace la classe?
- 22. déclaration de classe pour ruby
- 23. Appeler une méthode de classe dans une classe
- 24. appelant une autre méthode dans super classe dans ruby
- 25. Une classe interne privée synthétise une classe anonyme inattendue
- 26. Ruby classe question
- 27. Existe-t-il un moyen d'appeler une méthode Class privée à partir d'une instance dans Ruby?
- 28. Comment nommez-vous une classe/un module/un module comme
- 29. méthode dans la classe partielle non répertoriée dans intellisense
- 30. Comment un module écrase-t-il une méthode dans la classe parente d'une classe dans laquelle il est inclus?
Bon sang. Je pensais que c'était possible, mais j'espérais que ce ne serait pas hackish ... Oh bien. Je suppose que je trouverai une façon plus Ruby-ish de le faire. Merci cependant - vous avez répondu à ma question. – c4757p
Vous devriez attendre d'autres réponses, je peux aussi bien me tromper. BTW, qu'est-ce que vous voulez atteindre avec des cours privés? Oh, une autre chose: les variables d'instance sont toujours _private_ dans Ruby, et afin de les exposer, vous devez créer des méthodes accesseur, mais personne ne considère que _hackish_. :) –
En fait, je pense que faire ça/est un peu hackish - c'est l'une des choses que je n'aime pas chez Ruby. L'autre est l'appel de fonction implicite stupide - je souhaite vraiment que je pourrais simplement se référer à une fonction par son nom sans l'appeler, sans utiliser de symbole ou de lambda. Je m'interface dynamiquement avec une bibliothèque externe en utilisant FFI, et je voulais garder les structures FFI C 'loin du module utilisable. – c4757p