Menu
Coddy logo textTech

Indicizzazione e append

Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 39 di 57.

obj[key] chiama il metodo [] e obj[key] = value chiama []=. Definirli dà a una classe la sintassi tra parentesi quadre degli array e degli hash, con il significato più adatto:

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"]

Output:

7
0

[] può accettare diversi argomenti, per esempio una riga e una colonna, e può controllarli. IndexError è l'errore consueto per una posizione che non esiste:

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

Output:

X.
no cell 3,0

<< è l'operatore di aggiunta. Restituire self consente di concatenare le chiamate, come list << a << b sugli array:

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

Output:

Dune | Emma | Ulysses

Un’assegnazione tramite []= restituisce il valore assegnato, non ciò che restituisce il metodo, come qualsiasi setter. Le parentesi quadre e << offrono a una classe un’interfaccia semplice e familiare:

inv["apple"] = 5          # chiama []=("apple", 5), l'espressione vale 5
inv["apple"]              # chiama []("apple")
shelf << "Dune" << "Emma"  # << restituisce self, quindi le chiamate possono essere concatenate
board[1, 2] = "X"         # []=(1, 2, "X")
challenge icon

Sfida

Facile

Completa la classe Inventory. inv[name] restituisce la quantità di un elemento (0 se sconosciuto), inv[name] = qty la imposta e inv << name aggiunge un elemento di quel tipo e restituisce l'inventario, così da poter concatenare le chiamate. to_s restituisce apple: 3, pear: 1 in ordine alfabetico dei nomi, omettendo gli elementi con quantità 0, oppure empty.

Il codice fornito legge i comandi: set apple 5, add apple pear pear (che concatena << per ogni nome), get apple e print, e stampa il risultato di get e print.

Il tuo codice va in inventory.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.

Provalo tu

require_relative 'inventory'

# Supplied input/output code: keep it as it is
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
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Ruby online