Ruby - Moduli e Mixin

I moduli sono un modo per raggruppare metodi, classi e costanti. I moduli offrono due vantaggi principali.

  • I moduli forniscono uno spazio dei nomi e prevengono conflitti di nome.

  • I moduli implementano la funzione di mixin .

I moduli definiscono uno spazio dei nomi, una sandbox in cui i tuoi metodi e le tue costanti possono giocare senza doversi preoccupare di essere calpestati da altri metodi e costanti.

Sintassi

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

Le costanti del modulo sono denominate proprio come le costanti di classe, con una lettera iniziale maiuscola. Anche le definizioni dei metodi sono simili: i metodi dei moduli sono definiti proprio come i metodi delle classi.

Come con i metodi di classe, si chiama un metodo di modulo facendo precedere il suo nome con il nome del modulo e un punto e si fa riferimento a una costante utilizzando il nome del modulo e due due punti.

Esempio

#!/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

Possiamo definire un altro modulo con lo stesso nome di funzione ma funzionalità diverse -

#!/usr/bin/ruby

# Module defined in moral.rb file

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

Come i metodi di classe, ogni volta che si definisce un metodo in un modulo, si specifica il nome del modulo seguito da un punto e quindi il nome del metodo.

Ruby richiede Statement

L'istruzione require è simile all'istruzione include di C e C ++ e all'istruzione import di Java. Se un terzo programma desidera utilizzare un modulo definito, può semplicemente caricare i file del modulo utilizzando l' istruzione require di Ruby -

Sintassi

require filename

Qui non è necessario dare .rb estensione insieme a un nome file.

Esempio

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

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

Qui stiamo usando $LOAD_PATH << '.'per fare in modo che Ruby sappia che i file inclusi devono essere cercati nella directory corrente. Se non vuoi usare $ LOAD_PATH, puoi usarerequire_relative per includere file da una directory relativa.

IMPORTANT- Qui, entrambi i file contengono lo stesso nome di funzione. Quindi, ciò comporterà un'ambiguità del codice durante l'inclusione nel programma chiamante, ma i moduli evitano questa ambiguità del codice e siamo in grado di chiamare la funzione appropriata usando il nome del modulo.

Ruby include Statement

Puoi incorporare un modulo in una classe. Per incorporare un modulo in una classe, utilizza l' istruzione include nella classe:

Sintassi

include modulename

Se un modulo è definito in un file separato, è necessario includere quel file utilizzando l' istruzione require prima di incorporare il modulo in una classe.

Esempio

Considera il seguente modulo scritto nel file 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

Ora puoi includere questo modulo in una classe come segue:

#!/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

Questo produrrà il seguente risultato:

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

Mixins in Ruby

Prima di passare a questa sezione, si presume che tu abbia la conoscenza dei concetti orientati agli oggetti.

Quando una classe può ereditare funzionalità da più di una classe genitore, si suppone che la classe mostri ereditarietà multipla.

Ruby non supporta direttamente l'ereditarietà multipla, ma i moduli Ruby hanno un altro meraviglioso utilizzo. In un colpo solo, eliminano praticamente la necessità di eredità multipla, fornendo una struttura chiamata mixin .

I mixin ti offrono un modo meravigliosamente controllato per aggiungere funzionalità alle classi. Tuttavia, il loro vero potere emerge quando il codice nel mixin inizia a interagire con il codice nella classe che lo utilizza.

Esaminiamo il seguente codice di esempio per comprendere meglio il 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

Il modulo A è costituito dai metodi a1 e a2. Il modulo B è costituito dai metodi b1 e b2. La classe Sample include entrambi i moduli A e B. La classe Sample può accedere a tutti e quattro i metodi, ovvero a1, a2, b1 e b2. Pertanto, puoi vedere che la classe Sample eredita da entrambi i moduli. Quindi, puoi dire che la classe Sample mostra ereditarietà multipla o un mixin .