Ruby Modules
Модули - это способ группировки методов, классов и констант. Модули дают нам два основных преимущества.
Модули предоставляют пространство имен и предотвращают конфликты имен.
Модули реализуют возможность микширования (mixin).
Модули определяют пространство имен, «песочницу», в которой ваши методы и константы могут играть, не беспокоясь о том, что на них наступят другие методы и константы.
Синтаксис:
module Identifier
statement1
statement2
..................
end
Константы модуля называются так же, как константы класса, с начальной буквы и в верхнем регистре. Определения методов тоже выглядят одинаково: методы модуля определяются так же, как методы класса.
Как и в случае с методами класса, вы вызываете метод модуля, предваряя его имя именем модуля и точкой, и вы ссылаетесь на константу, используя имя модуля и два двоеточия.
Пример:
#!/usr/bin/ruby
# Модуль, определенный в файле trig.rb
module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
def Trig.cos(x)
# ..
end
end
Мы можем определить еще один модуль с тем же именем функции, но с другой функциональностью:
#!/usr/bin/ruby
# Модуль, определенный в файле moral.rb
module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin (badness)
# ...
end
end
Как и методы класса, всякий раз, когда вы определяете метод в модуле, вы указываете имя модуля, за которым следует точка, а затем имя метода.
Ruby require Statement:
Оператор require аналогичен оператору include C и C ++ и оператору импорта Java. Если третья программа хочет использовать какой-либо определенный модуль, она может просто загрузить файлы модуля с помощью инструкции require:
Синтаксис:
require filename
Здесь необязательно указывать расширение .rb вместе с именем файла.
Пример:
require 'trig.rb'
require 'mental'
y = Trig.sin (Trig :: PI / 4 )
wrongdoing = Moral.sin (Moral :: VERY_BAD)
ВАЖНО: Оба файла содержат одинаковое имя функции. Таким образом, это приведет к неоднозначности кода при включении в вызывающую программу, но модули избегают этой неоднозначности кода, и мы можем вызывать соответствующую функцию, используя имя модуля.
Ruby include Statement:
Вы можете встроить модуль в класс. Чтобы встроить модуль в класс, вы используете оператор include в классе:
Синтаксис:
include modulename
Если модуль определен в отдельном файле, то перед встраиванием модуля в класс необходимо включить этот файл с помощью оператора require.
Пример:
Рассмотрим следующий модуль, написанный в файле Week.rb.
module Week
FIRST_DAY = "Воскресенье"
def Week.weeks_in_month
puts "У вас четыре недели в месяце"
end
def Week.weeks_in_year
puts "У вас 52 недели в году"
end
end
Теперь вы можете включить этот модуль в класс следующим образом:
#!/usr/bin/ruby
require "Week"
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
Это даст следующий результат:
Воскресенье
У вас четыре недели в месяце
У вас 52 недели в году
Воскресенье
120
Mixins in Ruby:
Прежде чем перейти к этому разделу, предполагается, что вы знакомы с объектно-ориентированными концепциями.
Когда класс может наследовать функции более чем одного родительского класса, предполагается, что у этого класса будет множественное наследование.
Ruby не поддерживает множественное наследование напрямую, но модули Ruby имеют еще одно замечательное применение. Одним махом они в значительной степени устраняют необходимость множественного наследования, предоставляя возможность, называемую миксином.
Миксины (mixins) дают вам чудесно управляемый способ добавления функциональности в классы. Однако их истинная сила проявляется, когда код в миксине начинает взаимодействовать с кодом в классе, который его использует.
Давайте рассмотрим следующий пример кода, чтобы понять, что такое миксин:
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 наследуется от обоих модулей. Таким образом, вы можете сказать, что образец класса показывает множественное наследование или mixin (миксин)