Ruby - Módulos y Mixins

Los módulos son una forma de agrupar métodos, clases y constantes. Los módulos le brindan dos beneficios principales.

  • Los módulos proporcionan un espacio de nombres y evitan conflictos de nombres.

  • Los módulos implementan la función mixin .

Los módulos definen un espacio de nombres, una caja de arena en la que sus métodos y constantes pueden jugar sin tener que preocuparse por ser pisoteados por otros métodos y constantes.

Sintaxis

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

Las constantes del módulo se nombran igual que las constantes de clase, con una letra mayúscula inicial. Las definiciones de métodos también son similares: los métodos de módulo se definen como los métodos de clase.

Al igual que con los métodos de clase, llama a un método de módulo anteponiendo su nombre con el nombre del módulo y un punto, y hace referencia a una constante usando el nombre del módulo y dos dos puntos.

Ejemplo

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

Podemos definir un módulo más con el mismo nombre de función pero diferente funcionalidad -

#!/usr/bin/ruby

# Module defined in moral.rb file

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

Al igual que los métodos de clase, cada vez que define un método en un módulo, especifica el nombre del módulo seguido de un punto y luego el nombre del método.

Ruby requiere declaración

La declaración require es similar a la declaración de inclusión de C y C ++ y la declaración de importación de Java. Si un tercer programa quiere usar cualquier módulo definido, simplemente puede cargar los archivos del módulo usando la declaración require de Ruby -

Sintaxis

require filename

Aquí, no es necesario dar .rb extensión junto con un nombre de archivo.

Ejemplo

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

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

Aquí estamos usando $LOAD_PATH << '.'para que Ruby sepa que los archivos incluidos deben buscarse en el directorio actual. Si no desea usar $ LOAD_PATH, puede usarrequire_relative para incluir archivos de un directorio relativo.

IMPORTANT- Aquí, ambos archivos contienen el mismo nombre de función. Por lo tanto, esto resultará en ambigüedad de código mientras se incluye en el programa de llamada, pero los módulos evitan esta ambigüedad de código y podemos llamar a la función apropiada usando el nombre del módulo.

Ruby incluye declaración

Puede incrustar un módulo en una clase. Para incrustar un módulo en una clase, usa la declaración de inclusión en la clase:

Sintaxis

include modulename

Si un módulo se define en un archivo separado, entonces es necesario incluir ese archivo usando la declaración require antes de incrustar el módulo en una clase.

Ejemplo

Considere el siguiente módulo escrito en el archivo 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

Ahora, puede incluir este módulo en una clase de la siguiente manera:

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

Esto producirá el siguiente resultado:

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

Mixins en Ruby

Antes de pasar por esta sección, asumimos que tiene el conocimiento de los conceptos orientados a objetos.

Cuando una clase puede heredar características de más de una clase principal, se supone que la clase muestra herencia múltiple.

Ruby no admite la herencia múltiple directamente, pero los módulos Ruby tienen otro uso maravilloso. De un plumazo, eliminan prácticamente la necesidad de herencia múltiple, proporcionando una función llamada mixin .

Los Mixins te brindan una forma maravillosamente controlada de agregar funcionalidad a las clases. Sin embargo, su verdadero poder surge cuando el código en el mixin comienza a interactuar con el código de la clase que lo usa.

Examinemos el siguiente código de muestra para comprender mejor el 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

El módulo A consta de los métodos a1 y a2. El módulo B consta de los métodos b1 y b2. La clase Sample incluye los módulos A y B. La clase Sample puede acceder a los cuatro métodos, a saber, a1, a2, b1 y b2. Por lo tanto, puede ver que la clase Sample hereda de ambos módulos. Por lo tanto, puede decir que la clase Sample muestra una herencia múltiple o una mezcla .