Ruby - Modules et Mixins

Les modules sont un moyen de regrouper des méthodes, des classes et des constantes. Les modules vous offrent deux avantages majeurs.

  • Les modules fournissent un espace de noms et évitent les conflits de noms.

  • Les modules implémentent la fonction mixin .

Les modules définissent un espace de noms, un bac à sable dans lequel vos méthodes et constantes peuvent jouer sans avoir à vous soucier d'être piétiné par d'autres méthodes et constantes.

Syntaxe

module Identifier
   statement1
   statement2
   ...........
end

Les constantes de module sont nommées comme les constantes de classe, avec une lettre majuscule initiale. Les définitions de méthode se ressemblent également: les méthodes de module sont définies comme les méthodes de classe.

Comme pour les méthodes de classe, vous appelez une méthode de module en faisant précéder son nom du nom du module et d'un point, et vous référencez une constante en utilisant le nom du module et deux deux-points.

Exemple

#!/usr/bin/ruby

# Module defined in trig.rb file

module Trig
   PI = 3.141592654
   def Trig.sin(x)
   # ..
   end
   def Trig.cos(x)
   # ..
   end
end

Nous pouvons définir un module supplémentaire avec le même nom de fonction mais des fonctionnalités différentes -

#!/usr/bin/ruby

# Module defined in moral.rb file

module Moral
   VERY_BAD = 0
   BAD = 1
   def Moral.sin(badness)
   # ...
   end
end

Comme les méthodes de classe, chaque fois que vous définissez une méthode dans un module, vous spécifiez le nom du module suivi d'un point, puis du nom de la méthode.

Ruby require Statement

L'instruction require est similaire à l'instruction include de C et C ++ et à l'instruction import de Java. Si un troisième programme souhaite utiliser un module défini, il peut simplement charger les fichiers du module à l'aide de l' instruction Ruby require -

Syntaxe

require filename

Ici, il n'est pas nécessaire de donner .rb extension avec un nom de fichier.

Exemple

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)

Ici, nous utilisons $LOAD_PATH << '.'pour que Ruby sache que les fichiers inclus doivent être recherchés dans le répertoire courant. Si vous ne souhaitez pas utiliser $ LOAD_PATH, vous pouvez utiliserrequire_relative pour inclure des fichiers d'un répertoire relatif.

IMPORTANT- Ici, les deux fichiers contiennent le même nom de fonction. Donc, cela entraînera une ambiguïté du code lors de l'inclusion dans le programme d'appel, mais les modules évitent cette ambiguïté du code et nous pouvons appeler la fonction appropriée en utilisant le nom du module.

Instruction Ruby include

Vous pouvez intégrer un module dans une classe. Pour incorporer un module dans une classe, vous utilisez l' instruction include dans la classe -

Syntaxe

include modulename

Si un module est défini dans un fichier séparé, il est alors nécessaire d'inclure ce fichier à l'aide de l' instruction require avant d'incorporer le module dans une classe.

Exemple

Considérez le module suivant écrit dans le fichier support.rb .

module Week
   FIRST_DAY = "Sunday"
   def Week.weeks_in_month
      puts "You have four weeks in a month"
   end
   def Week.weeks_in_year
      puts "You have 52 weeks in a year"
   end
end

Maintenant, vous pouvez inclure ce module dans une classe comme suit -

#!/usr/bin/ruby
$LOAD_PATH << '.'
require "support"

class Decade
include Week
   no_of_yrs = 10
   def no_of_months
      puts Week::FIRST_DAY
      number = 10*12
      puts number
   end
end
d1 = Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months

Cela produira le résultat suivant -

Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120

Mixins en rubis

Avant de parcourir cette section, nous supposons que vous avez la connaissance des concepts orientés objet.

Lorsqu'une classe peut hériter des fonctionnalités de plusieurs classes parentes, la classe est censée afficher plusieurs héritages.

Ruby ne prend pas directement en charge l'héritage multiple, mais les modules Ruby ont une autre utilisation merveilleuse. D'un seul coup, ils éliminent à peu près le besoin d'héritage multiple, offrant une fonction appelée mixin .

Les mixins vous offrent un moyen merveilleusement contrôlé d'ajouter des fonctionnalités aux classes. Cependant, leur véritable pouvoir sort lorsque le code du mixin commence à interagir avec le code de la classe qui l'utilise.

Examinons l'exemple de code suivant pour mieux comprendre mixin -

module A
   def a1
   end
   def a2
   end
end
module B
   def b1
   end
   def b2
   end
end

class Sample
include A
include B
   def s1
   end
end

samp = Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1

Le module A comprend les méthodes a1 et a2. Le module B comprend les méthodes b1 et b2. La classe Sample comprend les modules A et B. La classe Sample peut accéder aux quatre méthodes, à savoir, a1, a2, b1 et b2. Par conséquent, vous pouvez voir que la classe Sample hérite des deux modules. Ainsi, vous pouvez dire que la classe Sample montre un héritage multiple ou un mixin .