Модули и include
Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 27 из 57.
Модуль — это именованная группа методов. Он не может создавать объекты, но класс может использовать его с помощью include, и тогда каждый экземпляр получает методы модуля, как если бы они были определены в классе. Это называется примесью (mixin):
module Greetable
def greet
"Hello, I am #{name}"
end
end
class Person
include Greetable
attr_reader :name
def initialize(name)
@name = name
end
end
puts Person.new("Ada").greetВывод:
Hello, I am AdaМетоды модуля могут вызывать методы, предоставляемые классом, например указанный выше name. Поэтому один модуль может использоваться совершенно разными классами, если каждый из них предоставляет всё, что использует модуль:
module Greetable
def greet
"Hello, I am #{name}"
end
end
class Robot
include Greetable
def name
"R2"
end
end
class City
include Greetable
def name
"Paris"
end
end
puts Robot.new.greet
puts City.new.greetВывод:
Hello, I am R2
Hello, I am ParisУ класса может быть только один суперкласс, но он может включать любое количество модулей. include? проверяет, включает ли класс модуль, а модуль появляется в ancestors сразу после класса — именно там Ruby ищет его методы:
module Swimmer
def swim
"swimming"
end
end
module Flyer
def fly
"flying"
end
end
class Duck
include Swimmer
include Flyer
end
d = Duck.new
puts "#{d.swim}, #{d.fly}"
puts Duck.include?(Flyer)
p Duck.ancestors.take(3)Результат:
swimming, flying
true
[Duck, Flyer, Swimmer]Модули также объединяют связанные классы и константы под одним именем — пространством имён, — чтобы имена не конфликтовали. Shop::Item и Game::Item — это разные классы:
module Shop
TAX = 0.2
class Item
def label
"shop item, tax #{TAX}"
end
end
end
puts Shop::Item.new.label
puts Shop::TAXВывод:
shop item, tax 0.2
0.2Задание
ЛегкоЗавершите модули и классы. Greetable#greet возвращает Hello, I am Ada, используя name объекта. Walkable#walk(steps) добавляет шаги к счётчику, хранящемуся в @steps (при первом использовании он начинается со значения nil), и возвращает Ada walked 30 steps — накопленный итог. Person подключает оба модуля; Robot подключает только Greetable, и его имя состоит из R- и следующего за ним серийного номера.
Предоставленный код создаёт человека и робота из первой строки (Ada 7), затем выполняет команды greet p, greet r или walk 10 (для человека), выводит результат каждой команды и наконец robot walks: false.
Ваш код должен находиться в файлах greetable.rb, walkable.rb, person.rb и robot.rb. В main.rb находится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
require_relative 'greetable'
require_relative 'walkable'
require_relative 'person'
require_relative 'robot'
# Предоставленный код ввода/вывода: оставьте его как есть
input = []
while (line = gets)
input << line.chomp
end
name, serial = input[0].split
person = Person.new(name)
robot = Robot.new(serial)
input.drop(1).each do |line|
command, arg = line.split
if command == "walk"
puts person.walk(arg.to_i)
else
target = arg == "p" ? person : robot
puts target.greet
end
end
puts "robot walks: #{Robot.include?(Walkable)}"
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовПеременные экземпляраМетоды и selfto_s и inspectПовторение — читательский билет4Инкапсуляция
Приватные методыЗащищённые методыПриватные сеттерыЗащита состоянияПовторение — торговый автомат7Полиморфизм и утиная типизация
ПолиморфизмУтиная типизацияАбстрактные методыcase и классыПовторение — способы оплаты10Шаблоны проектирования, часть 2
Делегирование с помощью ForwardableШаблон декоратораШаблон строителяШаблон состояния2Аксессоры и self
Чтение и записьПользовательские сеттерыself в методахИдентичность и равенствоПовторение — список контактов5Наследование
ПодклассыПереопределение методовВызов superis_a? и предкиПовторение — расчёт зарплаты сотрудников8Специальные методы
Равенство и хешированиеМетоды операторовИндексация и добавлениеПользовательские коллекцииПовторение — дроби11Проект: Управление библиотекой
Книги и читателиВыдача книг3Методы и переменные классов
Методы классовПеременные экземпляра классаКонстантыФабричные методыПовторение — коды купонов6Модули и примеси
Модули и includeРасширение объектовМодуль ComparableМодуль EnumerableПовторение — спортивная лига9Паттерны проектирования. Часть 1
Паттерн «Одиночка»Фабричный паттернПаттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор Ruby