Question

Je viens de Java et maintenant je travaille davantage avec Ruby.

Une caractéristique linguistique que je ne connais pas bien est le module . Je me demande en quoi consiste exactement un module et quand en utilisez-vous un, et pourquoi utiliser un module sur une classe ?

Était-ce utile?

La solution

La première réponse est bonne et donne quelques réponses structurelles, mais une autre approche consiste à réfléchir à ce que vous faites. Les modules visent à fournir des méthodes que vous pouvez utiliser dans plusieurs classes - considérez-les comme des "bibliothèques". (comme vous le verriez dans une application Rails). Les classes concernent les objets; les modules concernent les fonctions.

Par exemple, les systèmes d'authentification et d'autorisation sont de bons exemples de modules. Les systèmes d'authentification fonctionnent sur plusieurs classes au niveau de l'application (les utilisateurs sont authentifiés, les sessions gèrent l'authentification, de nombreuses autres classes agissent différemment en fonction de l'état auth), de sorte que les systèmes d'authentification agissent comme des API partagées.

Vous pouvez également utiliser un module lorsque vous avez partagé des méthodes entre plusieurs applications (encore une fois, le modèle de bibliothèque est bon ici).

Autres conseils

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ class                     ║ module                          ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated       ║ can *not* be instantiated       ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage         ║ object creation           ║ mixin facility. provide         ║
║               ║                           ║   a namespace.                  ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass    ║ module                    ║ object                          ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods       ║ class methods and         ║ module methods and              ║
║               ║   instance methods        ║   instance methods              ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance   ║ inherits behaviour and can║ No inheritance                  ║
║               ║   be base for inheritance ║                                 ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion     ║ cannot be included        ║ can be included in classes and  ║
║               ║                           ║   modules by using the include  ║
║               ║                           ║   command (includes all         ║
║               ║                           ║   instance methods as instance  ║
║               ║                           ║   methods in a class/module)    ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension     ║ can not extend with       ║ module can extend instance by   ║
║               ║   extend command          ║   using extend command (extends ║
║               ║   (only with inheritance) ║   given instance with singleton ║
║               ║                           ║   methods from module)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

Je suis surpris que personne ne l'ait encore dit.

Le demandeur étant issu d'un environnement Java (et moi-même), voici une analogie qui aide.

Les classes ressemblent simplement à des classes Java.

Les modules ressemblent aux classes statiques Java. Pensez à la classe Math en Java. Vous ne l'instanciez pas et vous réutilisiez les méthodes de la classe statique (par exemple, Math.random () ).

En gros, le module ne peut pas être instancié. Lorsqu'une classe inclut un module, une superclasse de proxy est générée et permet d'accéder à toutes les méthodes du module ainsi qu'à celles de la classe.

Un module peut être inclus par plusieurs classes. Les modules ne peuvent pas être hérités, mais ce "mixin" Le modèle fournit un type utile de "multiple héritages". Les puristes d'OO ne seront pas d'accord avec cette affirmation, mais ne laissez pas la pureté entraver votre travail.

(Cette réponse était à l'origine liée à http://www.rubycentral.com/pickaxe/classes.html , mais ce lien et son domaine ne sont plus actifs.)

Le module en Ruby correspond, dans une certaine mesure, à la Java classe abstraite - a des méthodes d'instance, les classes peuvent en hériter (via include , Les gars de Ruby appellent cela un "mixin"), mais n’ont pas de cas. Il existe d’autres différences mineures, mais ces informations suffisent pour vous aider à démarrer.

espace de noms: les modules sont des espaces de noms ... inexistants en java;)

Je suis également passé de Java et de python à Ruby, je me souviens même de la même question ...

Donc la réponse la plus simple est que ce module est un espace de noms, qui n'existe pas en Java. En Java, l'état d'esprit le plus proche de l'espace de nom est un package .

Ainsi, un module en ruby ??ressemble à quoi en java:
class? Non
interface? Non
classe abstraite? Non
package? Oui (peut-être)

Méthodes statiques dans les classes en java: identiques aux méthodes dans les modules en ruby ??

En Java, l’unité minimum est une classe, vous ne pouvez pas avoir de fonction en dehors d’une classe. Cependant en ruby ??c'est possible (comme en python).

Alors, qu'est-ce qui entre dans un module?
classes, méthodes, constantes. Le module les protège sous cet espace de noms.

Aucune instance: les modules ne peuvent pas être utilisés pour créer des instances

Mixed ins: parfois, les modèles d'héritage ne conviennent pas aux classes, mais en termes de fonctionnalités, vous souhaitez regrouper un ensemble de classes / méthodes / constantes

Règles relatives aux modules en ruby:
- Les noms de modules sont UpperCamelCase
- les constantes dans les modules sont ALL CAPS (cette règle est la même pour toutes les constantes ruby ??et n'est pas spécifique aux modules)

- méthodes d'accès: utilisation. opérateur
- constantes d'accès: use :: symbol

exemple simple de module:

module MySampleModule
  CONST1 = "some constant"

  def self.method_one(arg1)
    arg1 + 2
  end
end

comment utiliser des méthodes dans un module:

puts MySampleModule.method_one(1) # prints: 3

comment utiliser les constantes d'un module:

puts MySampleModule::CONST1 # prints: some constant

Quelques autres conventions sur les modules:
Utilisez un module dans un fichier (comme des classes ruby, une classe par fichier ruby)

Ligne de fond: un module est un croisement entre une classe statique / utilitaire et un mixin.

Les

mixins sont des morceaux réutilisables de "partiels". mise en œuvre, qui peut être combiné (ou composé) dans un mix & amp; correspondre à la mode, pour aider à écrire de nouvelles classes. Ces classes peuvent également avoir leur propre état et / ou code, bien sûr.

Classe

Lorsque vous définissez une classe, vous définissez un plan pour un type de données.  classe hold data, ont une méthode qui interagit avec ces données et est utilisée pour instancier des objets.

Module

  • Les modules permettent de regrouper des méthodes, des classes et des constantes.

  • Les modules vous apportent deux avantages majeurs:

    = > Les modules fournissent un espace de noms et empêchent les conflits de noms. Les espaces de noms aident à éviter les conflits avec des fonctions et des classes du même nom écrites par quelqu'un d'autre.

    = > Les modules implémentent la fonction mixin.

  

(y compris Module dans Klazz donne des exemples d’accès de Klazz à Module   méthodes. )

     

(étendre Klazz avec Mod en donnant à la classe Klazz l'accès aux méthodes Mods.)

Tout d'abord, certaines similitudes qui n'ont pas encore été mentionnées. Ruby supporte les classes ouvertes, mais les modules sont aussi ouverts. Après tout, Class hérite de Module dans la chaîne d’héritage de classe et ainsi, Class et Module ont un comportement similaire.

Mais vous devez vous demander quel est le but d'avoir à la fois une classe et un module dans un langage de programmation? Une classe est censée être un modèle pour la création d'instances, et chaque instance est une variante réalisée du modèle. Une instance est juste une variation réalisée d'un plan (la classe). Naturellement, les classes fonctionnent comme une création d’objet. De plus, comme nous souhaitons parfois qu’un modèle soit dérivé d’un autre, les classes sont conçues pour prendre en charge l’héritage.

Les modules ne peuvent pas être instanciés, ne créent pas d'objets et ne supportent pas l'héritage. Alors rappelez-vous qu'un module n'hérite PAS d'un autre!

Alors, quel est l’intérêt d’avoir des modules dans un langage? Une utilisation évidente des modules est de créer un espace de noms, et vous le remarquerez également avec d'autres langues. Encore une fois, ce qui est bien avec Ruby, c’est que les modules peuvent être rouverts (tout comme les classes). Et c’est un grand usage lorsque vous souhaitez réutiliser un espace de noms dans différents fichiers Ruby:

module Apple
  def a
    puts 'a'
  end
end

module Apple 
  def b
    puts 'b'
  end
end

class Fruit
  include Apple
end

 > f = Fruit.new
 => #<Fruit:0x007fe90c527c98> 
 > f.a
 => a
 > f.b
 => b

Mais il n'y a pas d'héritage entre les modules:

module Apple
  module Green
    def green
      puts 'green'
    end
  end
end

class Fruit
  include Apple
end

> f = Fruit.new
 => #<Fruit:0x007fe90c462420> 
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>

Le module Apple n'a hérité d'aucune méthode du module Green et lorsque nous avons inclus Apple dans la classe Fruit, les méthodes du module Apple sont ajoutées à la chaîne d'ancêtres d'instances Apple, mais pas des méthodes du module Green, même bien que le module vert ait été défini dans le module Apple.

Alors, comment pouvons-nous accéder à la méthode verte? Vous devez l'inclure explicitement dans votre classe:

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

Mais Ruby a une autre utilisation importante pour les modules. Ceci est l'installation Mixin, que je décris dans une autre réponse sur SO. Mais pour résumer, mixins vous permet de définir des méthodes dans la chaîne d'objets d'héritage. Grâce à mixins, vous pouvez ajouter des méthodes à la chaîne d'héritage d'instances d'objet (include) ou à la classe singleton_class de self (extend).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top