Menu
Coddy logo textTech

사용자 정의 컬렉션

Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 40번째.

컬렉션 클래스는 여러 특수 메서드를 결합합니다. Enumerable과 함께 사용하는 each, 항목을 추가하는 <<, size, 그리고 출력을 위한 to_s와 inspect입니다. 배열에서처럼 each는 블록 없이도 작동하여 to_enum을 사용해 열거자를 반환해야 합니다.

class TodoList
  include Enumerable

  def initialize
    @items = []
  end

  def <<(item)
    @items << item
    self
  end

  def each
    return to_enum(:each) unless block_given?

    @items.each { |item| yield item }
    self
  end
end

list = TodoList.new << "wash" << "shop" << "cook"
list.each.with_index(1) { |item, n| puts "#{n}. #{item}" }
p list.select { |i| i.include?("o") }

출력:

1. wash
2. shop
3. cook
["shop", "cook"]

block_given?은 호출자가 블록을 전달했는지 알려 줍니다. 블록 없이 반환된 열거자는 each.with_index, each_slice 또는 next와 같은 연결을 지원합니다:

class Countdown
  include Enumerable

  def initialize(from)
    @from = from
  end

  def each
    return to_enum(:each) unless block_given?

    @from.downto(1) { |n| yield n }
  end
end

e = Countdown.new(3).each
puts e.next
puts e.next
p Countdown.new(5).each_slice(2).to_a

출력:

3
2
[[5, 4], [3, 2], [1]]

to_s는 사용자를 위한 친숙한 텍스트이고 inspect는 프로그래머를 위한 간단한 요약입니다. 컬렉션의 경우 inspect는 일반적으로 모든 요소 대신 클래스와 크기를 표시합니다:

class TodoList
  include Enumerable

  def initialize(*items)
    @items = items
  end

  def each(&block)
    @items.each(&block)
  end

  def size
    @items.size
  end

  def to_s
    map.with_index(1) { |item, n| "#{n}. #{item}" }.join("\n")
  end

  def inspect
    "#<TodoList #{size} items>"
  end
end

list = TodoList.new("wash", "shop")
puts list
p list

출력:

1. wash
2. shop
#<TodoList 2 항목>

Enumerable은 count를 제공하지만 size, empty?, << 또는 []는 제공하지 않습니다. 이러한 메서드는 클래스에 속합니다. 요소가 어떻게 저장되는지는 클래스만 알고 있기 때문입니다. 이를 정의하면 호출하는 쪽에서 컬렉션을 배열처럼 사용할 수 있습니다:

def size
  @items.size
end

def empty?
  @items.empty?
end

def [](index)
  @items[index]
end
challenge icon

챌린지

쉬움

TodoList 클래스를 완성하세요. <<는 작업 텍스트를 추가하고 목록을 반환합니다. each는 작업들을 yield하며, 블록이 없을 때 to_enum(:each)를 반환합니다. Enumerable을 포함하세요. size는 작업 수를 반환합니다. to_s는 작업을 번호가 매겨진 줄로 반환하거나, 1. wash 또는 nothing to do를 반환하며, inspect는 #<TodoList 3 items>를 반환합니다.

제공된 코드는 <<를 연결하여 모든 입력 줄을 추가한 다음, 목록, 목록에 대한 p, each.with_index(1)를 통해 !가 붙은 번호가 매겨진 작업을 1! wash 형식으로 출력하고, o를 포함하는 작업의 수와 알파벳순으로 첫 번째 작업을 출력합니다.

코드는 todo_list.rb에 작성하세요. main.rb에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.

직접 해보기

require_relative 'todo_list'

# 제공된 입력/출력 코드: 있는 그대로 유지하세요
input = []
while (line = gets)
  input << line.chomp
end
list = input.reduce(TodoList.new) { |l, task| l << task }
puts list
p list
list.each.with_index(1) { |task, n| puts "#{n}! #{task}" }
puts "with o: #{list.count { |t| t.include?("o") }}"
puts "first: #{list.min}"
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 Ruby 컴파일러