Ruby - Módulos e Mixins

Módulos são uma forma de agrupar métodos, classes e constantes. Os módulos oferecem dois benefícios principais.

  • Os módulos fornecem um namespace e evitam conflitos de nomes.

  • Módulos implementam a facilidade mixin .

Os módulos definem um namespace, uma caixa de areia na qual seus métodos e constantes podem ser reproduzidos sem ter que se preocupar em ser pisado por outros métodos e constantes.

Sintaxe

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

As constantes de módulo são nomeadas exatamente como as constantes de classe, com uma letra inicial maiúscula. As definições de método também são semelhantes: os métodos de módulo são definidos como os métodos de classe.

Como acontece com os métodos de classe, você chama um método de módulo precedendo seu nome com o nome do módulo e um ponto, e faz referência a uma constante usando o nome do módulo e dois dois-pontos.

Exemplo

#!/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 mais um módulo com o mesmo nome de função, mas com funcionalidade diferente -

#!/usr/bin/ruby

# Module defined in moral.rb file

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

Como os métodos de classe, sempre que você define um método em um módulo, você especifica o nome do módulo seguido por um ponto e o nome do método.

Declaração de requerer Ruby

A instrução require é semelhante à instrução include do C e C ++ e à instrução import do Java. Se um terceiro programa deseja usar qualquer módulo definido, ele pode simplesmente carregar os arquivos do módulo usando a instrução require do Ruby -

Sintaxe

require filename

Aqui, não é necessário dar .rb extensão junto com um nome de arquivo.

Exemplo

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

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

Aqui estamos usando $LOAD_PATH << '.'para tornar Ruby ciente de que os arquivos incluídos devem ser pesquisados ​​no diretório atual. Se você não quiser usar $ LOAD_PATH, você pode usarrequire_relative para incluir arquivos de um diretório relativo.

IMPORTANT- Aqui, ambos os arquivos contêm o mesmo nome de função. Portanto, isso resultará em ambigüidade de código ao incluir na chamada do programa, mas os módulos evitam essa ambigüidade de código e podemos chamar a função apropriada usando o nome do módulo.

Ruby incluir declaração

Você pode incorporar um módulo em uma classe. Para incorporar um módulo em uma classe, você usa a instrução include na classe -

Sintaxe

include modulename

Se um módulo for definido em um arquivo separado, será necessário incluir esse arquivo usando a instrução require antes de incorporar o módulo em uma classe.

Exemplo

Considere o seguinte módulo escrito no arquivo 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

Agora, você pode incluir este módulo em uma classe da seguinte maneira -

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

Isso produzirá o seguinte resultado -

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

Mixins em Ruby

Antes de passar por esta seção, presumimos que você tenha conhecimento dos Conceitos Orientados a Objetos.

Quando uma classe pode herdar recursos de mais de uma classe pai, a classe deve mostrar herança múltipla.

O Ruby não suporta herança múltipla diretamente, mas os Módulos Ruby têm outro uso maravilhoso. De uma só vez, eles praticamente eliminam a necessidade de herança múltipla, fornecendo um recurso chamado mixin .

Mixins oferecem uma maneira maravilhosamente controlada de adicionar funcionalidade às classes. No entanto, seu verdadeiro poder surge quando o código no mixin começa a interagir com o código da classe que o usa.

Vamos examinar o seguinte código de amostra para entender o 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

O módulo A consiste nos métodos a1 e a2. Módulo B consiste nos métodos b1 e b2. A classe Sample inclui os módulos A e B. A classe Sample pode acessar todos os quatro métodos, a saber, a1, a2, b1 e b2. Portanto, você pode ver que a classe Sample é herdada de ambos os módulos. Assim, você pode dizer que a classe Sample mostra herança múltipla ou um mixin .