Написание собственного each
Реализуйте итерацию
«Написание собственного each» — бесплатный урок Ruby Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Ruby Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Ruby Academy содержит 4 уроков всего.
Реализация итерации
Итерация в Ruby строится вокруг одного метода: each. Написав собственный each, Вы определяете, как обходится коллекция, и открываете доступ ко всей экосистеме итерации.
class Trio
def each
yield 1
yield 2
yield 3
end
end
Trio.new.each { |n| puts n }each передаёт значения
Внутри each вызывайте yield один раз для каждого элемента. Блок, переданный вызывающим кодом, по очереди получает каждое значение.
class Days
NAMES = ["Mon", "Tue", "Wed"]
def each
NAMES.each { |d| yield d }
end
end
Days.new.each { |day| puts day }Хранение внутренних данных
Обычно each обходит данные, хранящиеся в переменной экземпляра.
class Stack
def initialize
@items = []
end
def push(x); @items << x; self; end
def each
@items.each { |i| yield i }
end
end
s = Stack.new
s.push(10).push(20)
s.each { |x| puts x }Пользовательский порядок обхода
Ваш each может выполнять итерацию в любом удобном для Вас порядке, например в обратном.
class Reversed
def initialize(arr); @arr = arr; end
def each
i = @arr.length - 1
while i >= 0
yield @arr[i]
i -= 1
end
end
end
Reversed.new([1, 2, 3]).each { |x| puts x }Передача нескольких значений
yield может передать несколько значений, которые блок получает как несколько параметров, например ключ и значение хеша.
class Pairs
def each
yield :a, 1
yield :b, 2
end
end
Pairs.new.each { |key, value| puts "#{key}=#{value}" }each возвращает self
По соглашению each возвращает саму коллекцию, чтобы вызовы можно было объединять в цепочку. Возврат self из each соответствует поведению встроенных коллекций.
class Box
def initialize(*x); @x = x; end
def each
@x.each { |i| yield i }
self
end
end
result = Box.new(1, 2).each { |i| }
puts result.classПроверка наличия блока
Защититесь от отсутствующего блока, чтобы отдельный вызов each не приводил к сбою: обычно в таком случае возвращают перечислитель, о котором мы поговорим позже.
class List
def initialize(*x); @x = x; end
def each
return @x.to_enum unless block_given?
@x.each { |i| yield i }
end
end
puts List.new(5, 6).each.classОснова для других методов
После появления each Вы можете создавать на его основе другие методы в том же классе.
class Numbers
def initialize(*n); @n = n; end
def each; @n.each { |i| yield i }; end
def total
sum = 0
each { |i| sum += i }
sum
end
end
puts Numbers.new(1, 2, 3, 4).totalВычисляемые последовательности
each не обязан хранить данные: он может создавать значения на лету.
class Evens
def initialize(limit); @limit = limit; end
def each
n = 0
while n <= @limit
yield n
n += 2
end
end
end
Evens.new(8).each { |x| puts x }Основа для Enumerable
Ваш each — единственный строительный блок, необходимый Enumerable. На следующем уроке Вы подключите этот модуль и бесплатно получите десятки методов.
class Range3
def each
(1..3).each { |n| yield n }
end
end
Range3.new.each { |n| print n }
putsСобираем всё вместе
Пользовательский each даёт полный контроль над итерацией:
yieldвызывается один раз для каждого элемента.- Вы можете обходить элементы в любом порядке, создавать значения или передавать пары.
- По соглашению возвращайте
self.
class Countdown
def initialize(from); @from = from; end
def each
@from.downto(1) { |n| yield n }
end
end
Countdown.new(3).each { |n| puts n }Быстрая проверка
Проверьте, насколько хорошо Вы поняли пользовательский each.
Повторение
Вы научились писать собственный each:
yieldпередаёт элементы в блок вызывающего кода.- Вы управляете порядком обхода и можете создавать значения.
- По соглашению возвращайте
self. each— основа для Enumerable.
class Squares
def initialize(n); @n = n; end
def each
(1..@n).each { |i| yield i * i }
end
end
Squares.new(4).each { |sq| puts sq }Часто задаваемые вопросы
Урок «Написание собственного each» бесплатный?
Да — полный текст урока «Написание собственного each» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Ruby Academy, подпишись на CoddyKit PRO. Курс Ruby Academy содержит 4 уроков всего.
Чему я научусь в уроке «Написание собственного each»?
Реализуйте итерацию Ты практикуешь Ruby Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Ruby Academy?
Предыдущий опыт не требуется. Ruby Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Написание собственного each»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Ruby Academy?
Да. Каждый урок Ruby Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Написание собственного each
- Подключение Enumerable
- Ленивые перечислители
- Объекты Enumerator