Indexação e Adição
Parte da seção Programação orientada a objetos do Journey de Ruby da Coddy. Lição 39 de 57.
obj[key] chama o método [], e obj[key] = value chama []=. Defini-los dá a uma classe a sintaxe de colchetes de arrays e hashes, com qualquer significado que seja adequado a ela:
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"]Saída:
7
0[] pode receber vários argumentos, por exemplo, uma linha e uma coluna, e pode verificá-los. IndexError é o erro usual para uma posição que não existe:
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
endSaída:
X.
no cell 3,0<< é o operador de anexação. Retornar self dele permite o encadeamento, como em list << a << b em arrays:
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 shelfSaída:
Dune | Emma | UlyssesUma atribuição por meio de []= retorna o valor atribuído, não o que o método retorna, como acontece com qualquer setter. Os colchetes e << dão à classe uma interface pequena e familiar:
inv["apple"] = 5 # chama []=("apple", 5), a expressão é 5
inv["apple"] # chama []("apple")
shelf << "Dune" << "Emma" # << retorna self, então encadeia
board[1, 2] = "X" # []=(1, 2, "X")Desafio
FácilComplete a classe Inventory. inv[name] retorna a quantidade de um item (0 quando desconhecido), inv[name] = qty define essa quantidade, e inv << name adiciona uma unidade desse item e retorna o inventário para que as chamadas possam ser encadeadas. to_s retorna apple: 3, pear: 1 em ordem alfabética dos nomes, excluindo itens com quantidade 0, ou empty.
O código fornecido lê comandos: set apple 5, add apple pear pear (que encadeia << para cada nome), get apple e print, e imprime o resultado de get e print.
Seu código deve estar em inventory.rb. main.rb contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
require_relative 'inventory'
# Código de entrada/saída fornecido: mantenha-o como está
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
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Classes e Objetos
Trabalhando com ArquivosDefinindo ClassesVariáveis de InstânciaMétodos e selfto_s e inspectRevisão - Cartão da Biblioteca4Encapsulamento
Métodos privadosMétodos protegidosSetters privadosProtegendo o estadoRevisão - Máquina de venda automática7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMétodos Abstratoscase e ClassesRevisão - Métodos de Pagamento2Acessores e self
Leitores e GravadoresSetters Personalizadosself nos MétodosIdentidade e IgualdadeRecapitulação - Lista de Contatos5Herança
SubclassesSobrescrita de métodosChamando superis_a? e ancestraisRevisão - Folha de pagamento da equipe8Métodos Especiais
Igualdade e hashMétodos de OperadoresIndexação e AdiçãoColeções PersonalizadasRevisão - Frações11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de Ruby online