인덱싱과 추가
Coddy Ruby 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 39번째.
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[]=를 통한 할당은 모든 setter와 마찬가지로 메서드가 반환하는 값이 아니라 할당된 값을 반환합니다. 대괄호와 <<는 클래스에 작고 익숙한 인터페이스를 제공합니다:
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
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 Ruby 컴파일러