Ruby - модули и миксины

Модули - это способ группировки методов, классов и констант. Модули дают вам два основных преимущества.

  • Модули предоставляют пространство имен и предотвращают конфликты имен .

  • Модули реализуют возможность микширования .

Модули определяют пространство имен, песочницу, в которой могут работать ваши методы и константы, не беспокоясь о том, что на них могут наступить другие методы и константы.

Синтаксис

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

Константы модуля называются так же, как константы класса, с начальной буквы в верхнем регистре. Определения методов тоже выглядят одинаково: методы модуля определяются так же, как методы класса.

Как и в случае с методами класса, вы вызываете метод модуля, предваряя его имя именем модуля и точкой, и вы ссылаетесь на константу, используя имя модуля и два двоеточия.

пример

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

Мы можем определить еще один модуль с тем же именем функции, но с другой функциональностью -

#!/usr/bin/ruby

# Module defined in moral.rb file

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

Как и методы класса, всякий раз, когда вы определяете метод в модуле, вы указываете имя модуля, за которым следует точка, а затем имя метода.

Заявление Ruby require

Оператор require аналогичен оператору include C и C ++ и оператору импорта Java. Если третья программа хочет использовать какой-либо определенный модуль, она может просто загрузить файлы модуля с помощью инструкции Ruby require -

Синтаксис

require filename

Здесь указывать .rb расширение вместе с именем файла.

пример

$LOAD_PATH << '.'

require 'trig.rb'
require 'moral'

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

Здесь мы используем $LOAD_PATH << '.'чтобы Ruby знал, что включенные файлы нужно искать в текущем каталоге. Если вы не хотите использовать $ LOAD_PATH, вы можете использоватьrequire_relative для включения файлов из относительного каталога.

IMPORTANT- Здесь оба файла содержат одно и то же имя функции. Таким образом, это приведет к неоднозначности кода при включении в вызывающую программу, но модули избегают этой неоднозначности кода, и мы можем вызвать соответствующую функцию, используя имя модуля.

Заявление о включении Ruby

Вы можете встроить модуль в класс. Чтобы встроить модуль в класс, вы используете оператор include в классе -

Синтаксис

include modulename

Если модуль определен в отдельном файле, то перед внедрением модуля в класс необходимо включить этот файл с помощью оператора require .

пример

Рассмотрим следующий модуль, записанный в файле 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

Теперь вы можете включить этот модуль в класс следующим образом:

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

Это даст следующий результат -

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

Миксины в Ruby

Прежде чем перейти к этому разделу, мы предполагаем, что вы знакомы с объектно-ориентированными концепциями.

Когда класс может наследовать функции более чем одного родительского класса, предполагается, что у этого класса будет множественное наследование.

Ruby не поддерживает множественное наследование напрямую, но у модулей Ruby есть еще одно замечательное применение. Одним махом они в значительной степени устраняют необходимость множественного наследования, предоставляя возможность, называемую миксином .

Миксины дают вам чудесно управляемый способ добавления функциональности к классам. Однако их истинная сила проявляется, когда код в миксине начинает взаимодействовать с кодом в классе, который его использует.

Давайте рассмотрим следующий пример кода, чтобы понять миксин:

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

Модуль A состоит из методов a1 и a2. Модуль B состоит из методов b1 и b2. Класс Sample включает оба модуля A и B. Класс Sample может получить доступ ко всем четырем методам, а именно a1, a2, b1 и b2. Таким образом, вы можете видеть, что класс Sample наследуется от обоих модулей. Таким образом, вы можете сказать, что образец класса показывает множественное наследование или миксин .