Расширение объектов
Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 28 из 57.
extend добавляет методы модуля одному объекту, а не всем экземплярам. Расширение класса добавляет их к объекту класса, поэтому они становятся методами класса:
module Describable
def describe
"#{name} has #{instance_methods(false).size} methods"
end
end
class Dog
extend Describable
def bark
"Woof"
end
def sit
"sits"
end
end
puts Dog.describeВывод:
Dog has 2 methodsМодуль, используемый с extend, может хранить состояние в переменных экземпляра класса. Каждый класс, который его расширяет, получает собственную копию в виде переменных экземпляра класса:
module Counted
def created
@created ||= 0
end
def record
@created = created + 1
end
end
class Order
extend Counted
end
class Invoice
extend Counted
end
Order.record
Order.record
Invoice.record
puts "#{Order.created} #{Invoice.created}"Вывод:
2 1extend также работает с одним объектом. Только этот объект получает методы; другие экземпляры его класса остаются без изменений, а is_a? имеет значение true только для расширенного объекта:
module Shiny
def polish
"#{self} is shining"
end
end
a = "car"
b = "bike"
a.extend(Shiny)
puts a.polish
puts a.is_a?(Shiny)
puts b.respond_to?(:polish)Результат:
car is shining
true
falseЭти два ключевых слова помещают методы одного и того же модуля в разные места. include делает их методами экземпляра класса, а extend — методами объекта, который расширяется:
class Order
include Printable # order.print_me (каждый экземпляр)
extend Counted # Order.record (сам класс)
end
item.extend(Shiny) # item.polish (только этот объект)Задание
ЛегкоДополните модуль Registry, который классы используют с помощью extend. register(name) добавляет имя в собственный список класса, хранящийся в @entries (создаваемом при первом использовании), и возвращает Plugin registered x; если имя уже есть в списке, возвращается Plugin already has x. entries возвращает список, а count — его размер. Plugin и Theme оба расширяют Registry и хранят отдельные списки.
Предоставленный код считывает строки plugin name или theme name, вызывает register у соответствующего класса и выводит ответ. В конце он выводит plugins: a, b (2) и themes: ... либо none (0) для пустого списка.
Ваш код должен находиться в файлах registry.rb, plugin.rb и theme.rb. В main.rb находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
require_relative 'registry'
require_relative 'plugin'
require_relative 'theme'
# Предоставленный код ввода/вывода: оставьте его как есть
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, name = line.split
target = kind == "plugin" ? Plugin : Theme
puts target.register(name)
end
[["plugins", Plugin], ["themes", Theme]].each do |label, klass|
list = klass.entries.empty? ? "none" : klass.entries.join(", ")
puts "#{label}: #{list} (#{klass.count})"
end
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
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