Индексация и добавление
Часть раздела Объектно-ориентированное программирование путешествия по Ruby на Coddy. Урок 39 из 57.
obj[key] вызывает метод [], а obj[key] = value вызывает []=. Их определение придаёт классу синтаксис квадратных скобок массивов и хешей с любым подходящим ему смыслом:
class Inventory
def initialize
@stock = Hash.new(0)
end
def [](name)
@stock[name]
end
def []=(name, qty)
@stock[name] = qty
end
end
inv = Inventory.new
inv["apple"] = 5
inv["apple"] += 2
puts inv["apple"]
puts inv["pear"]Вывод:
7
0[] может принимать несколько аргументов, например строку и столбец, и проверять их. IndexError — это обычная ошибка для несуществующей позиции:
class Board
def initialize(size)
@size = size
@cells = Array.new(size) { Array.new(size, ".") }
end
def [](row, col)
check(row, col)
@cells[row][col]
end
def []=(row, col, mark)
check(row, col)
@cells[row][col] = mark
end
def check(row, col)
raise IndexError, "no cell #{row},#{col}" unless row.between?(0, @size - 1) && col.between?(0, @size - 1)
end
end
b = Board.new(3)
b[1, 1] = "X"
puts b[1, 1] + b[0, 0]
begin
b[3, 0]
rescue IndexError => e
puts e.message
endВывод:
X.
no cell 3,0<< — это оператор добавления. Возврат self из него позволяет выполнять цепочку вызовов, например list << a << b для массивов:
class Shelf
def initialize
@books = []
end
def <<(title)
@books << title
self
end
def to_s
@books.join(" | ")
end
end
shelf = Shelf.new
shelf << "Dune" << "Emma" << "Ulysses"
puts shelfРезультат:
Dune | Emma | UlyssesПрисваивание через []= возвращает присвоенное значение, а не то, что возвращает метод, как и любой сеттер. Квадратные скобки и << предоставляют классу небольшой знакомый интерфейс:
inv["apple"] = 5 # вызывает []=("apple", 5), выражение равно 5
inv["apple"] # вызывает []("apple")
shelf << "Dune" << "Emma" # << возвращает self, поэтому можно выстраивать цепочку
board[1, 2] = "X" # []=(1, 2, "X")Задание
ЛегкоДополните класс Inventory. inv[name] возвращает количество элемента (0, если он неизвестен), inv[name] = qty задаёт его количество, а inv << name добавляет один экземпляр этого элемента и возвращает инвентарь, чтобы вызовы можно было объединять в цепочку. to_s возвращает apple: 3, pear: 1 в алфавитном порядке имён, пропуская элементы с количеством 0, либо empty.
Предоставленный код считывает команды: set apple 5, add apple pear pear (для каждого имени последовательно применяя <<), get apple и print, а также выводит результат выполнения get и print.
Ваш код должен находиться в inventory.rb. В main.rb содержится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
require_relative 'inventory'
# Предоставленный код ввода/вывода: оставьте его как есть
input = []
while (line = gets)
input << line.chomp
end
inv = Inventory.new
input.each do |line|
cmd, *args = line.split
case cmd
when "set" then inv[args[0]] = args[1].to_i
when "add" then args.reduce(inv) { |target, name| target << name }
when "get" then puts inv[args[0]]
else puts inv
end
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