Modules, namespaces et mixins
Les modules
- Définition et création
Il est possible de créer un module avec le mot-clé module.
Un module fonctionne un peu comme une classe. À la différence qu’il ne peut ni être instancié ni hérité. Il peut en revanche contenir des constantes, des variables, des méthodes (toujours avec self) ou des classes.
module MonModule
MA_CONSTANTE = 1
def self.une_methode()
...
end
class MaClasse
...
end
end- Inclusion de modules tiers
Tous les modules ne sont pas inclus par defaut, il est possible d’inclure des modules tiers avec le mot-clé require.
require 'date'L’inclusion avec le mot-clé require ne concerne que le gems installées globalement. Pour inclure un fichier dont le chemin est relatif au fichier courant, il faut utiliser le mot-clé require_relative.
require_relative 'fichier_local'Namespaces
Pour éviter les doublons de classes ou de méthodes, il est possible d’utiliser les modules comme des namespaces. Les classes et méthodes d’un module sont accessibles dans un autre module avec la syntaxe <NomModule>::. (Fonctionnement similaire aux namespaces C++)
Le but des namespaces est de regrouper les classes liées à une même logique.
Mixins
Le système de module permet aussi de faire de l’héritage “horizontal” car ils peuvent être inclus dans une class.
module Feature
def une_fonction_liee_a_la_feature
...
end
end
class MaClasse
include Feature
...
end
objet = MaClass.new
puts objet.une_fonction_liee_a_la_featureInclure un module dans une classe greffe automatiquement toutes les méthodes d’instance qui sont dans le module, au niveau de la classe.
- Méthode
included
Les modules ont tous une méthode de classe included. Si on la définit, cela permet de capturer à chaque fois qu’une module est inclus dans un sous-module ou dans une classe.
module Feature
def self.included(base) # base = classe dans laquelle le module est inclus
puts base
end
endIl est ainsi possible de modifier la classe dynamiquement à l’inclusion d’un module :
module Feature
def self.included(base) # base = classe dans laquelle le module est inclus
def base.une_nouvelle_methode
...
end
end
endextendau lieu deinclude
extend transfère les méthodes d’instance en méthode classe.
module Feature
def une_methode
...
end
end
class MaClasse
extend Feature
...
end
puts MaClass.une_methodeextend peut aussi être appelé depuis une instance de classe :
module Feature
def une_methode
...
end
end
class MaClasse
...
end
objet = MaClasse.new
objet.extend(Feature)
puts objet.une_methodeCela a pour effet de rajouter les méthodes du mixin dans l’instance, mais uniquement pour cette instance.
De la même manière que include a un hook included permettant de capturer quand un module est inclus dans une classe. Il existe un hook extended qui permet de capturer quand un module est étendu par une classe.