Menu
Coddy logo textTech

Indexieren und Anhängen

Teil des Abschnitts Objektorientierte Programmierung der Ruby-Journey von Coddy. Lektion 39 von 57.

obj[key] ruft die Methode [] auf, und obj[key] = value ruft []= auf. Durch ihre Definition erhält eine Klasse die Syntax von eckigen Klammern für Arrays und Hashes – mit einer beliebigen passenden Bedeutung:

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

Ausgabe:

7
0

[] kann mehrere Argumente übernehmen, zum Beispiel eine Zeile und eine Spalte, und sie überprüfen. IndexError ist der übliche Fehler für eine Position, die nicht existiert:

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

Ausgabe:

X.
no cell 3,0

<< ist der Anhängeoperator. Wenn du daraus self zurückgibst, ermöglicht das Verkettungen, wie etwa list << a << b bei 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 shelf

Ausgabe:

Dune | Emma | Ulysses

Eine Zuweisung über []= gibt den zugewiesenen Wert zurück, nicht das, was die Methode zurückgibt, wie bei jedem Setter. Klammern und << verleihen einer Klasse eine kleine, vertraute Schnittstelle:

inv["apple"] = 5          # ruft []=("apple", 5) auf, der Ausdruck ist 5
inv["apple"]              # ruft []("apple") auf
shelf << "Dune" << "Emma"  # << gibt self zurück, daher verkettet es
board[1, 2] = "X"         # []=(1, 2, "X")
challenge icon

Aufgabe

Einfach

Vervollständige die Klasse Inventory. inv[name] gibt die Menge eines Artikels zurück (0, wenn er unbekannt ist), inv[name] = qty legt sie fest, und inv << name fügt eine Einheit dieses Artikels hinzu und gibt das Inventar zurück, sodass Aufrufe verkettet werden können. to_s gibt apple: 3, pear: 1 in alphabetischer Reihenfolge der Namen zurück, wobei Artikel mit der Menge 0 ausgelassen werden, oder empty.

Der bereitgestellte Code liest Befehle: set apple 5, add apple pear pear (wobei << für jeden Namen verkettet wird), get apple und print, und gibt das Ergebnis von get und print aus.

Dein Code gehört in inventory.rb. main.rb enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

require_relative 'inventory'

# Gelieferter Ein-/Ausgabe-Code: belasse ihn wie er ist
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Ruby-Compiler