Menu
Coddy logo textTech

Fälle und Klassen

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

case kann anhand der Klasse eines Werts verzweigen. when Integer stimmt mit jeder Ganzzahl überein, weil case mit === vergleicht und Integer === 5 prüft, ob 5 ein Integer ist (is_a?):

def describe(value)
  case value
  when Integer then "integer #{value}"
  when Float then format("float %.2f", value)
  when String then "text of #{value.size} chars"
  when nil then "nothing"
  else "other: #{value.class}"
  end
end

[5, 2.5, "hi", nil, [1, 2]].each { |v| puts describe(v) }

Ausgabe:

integer 5
float 2.50
text of 2 chars
nothing
other: Array

Da === bei einer Klasse is_a? folgt, trifft ein when mit einer Oberklasse auch deren Unterklassen. Ordne die Zweige von der spezifischsten Klasse zur allgemeinsten an:

class Animal
end

class Dog < Animal
end

def kind(x)
  case x
  when Dog then "a dog"
  when Animal then "some animal"
  else "not an animal"
  end
end

puts kind(Dog.new)
puts kind(Animal.new)
puts kind("Rex")
puts Animal === Dog.new

Ausgabe:

a dog
some animal
not an animal
true

Ein when kann mehrere Klassen auflisten, und die Zweige können mit dem Wert echte Arbeit erledigen, etwa eine verschachtelte Struktur mit gemischten Typen zu summieren:

def total(value)
  case value
  when Integer, Float then value
  when String then value.to_f
  when Array then value.sum { |v| total(v) }
  when Hash then total(value.values)
  else 0
  end
end

puts total([1, "2.5", { a: 3, b: [4, nil] }])

Ausgabe:

10.5

Eine Verzweigung nach Klassen eignet sich für Werte, deren Klassen du keine neuen Methoden geben kannst, etwa Zahlen, Zeichenketten und Arrays, oder für Daten von außerhalb. Bei deinen eigenen Klassen solltest du Polymorphie bevorzugen: Eine neue Klasse benötigt dann eine neue Methode statt eines neuen Zweigs in jedem case:

# eigene Klassen: lass jede antworten
shape.area

# eingebaute Werte von außen: verzweige nach der Klasse
case value
when Integer then ...
when String then ...
end
challenge icon

Aufgabe

Einfach

Vervollständige den Helfer describe(value) in functions.rb mit einem case für die Klasse des Werts. Er gibt integer 5 (odd) oder integer 4 (even), float 2.50 mit zwei Dezimalstellen, text "hi" (2 chars), list of 3: 1, a, 2.5 (die mit to_s verbundenen Elemente), nothing für nil und other Symbol für alles andere zurück. Symbole sind die einzige andere Art in den Tests.

Der bereitgestellte Code wandelt jede Eingabezeile in einen Wert um (ganze Zahlen, Dezimalzahlen, [a,b]-Listen, nil, :name-Symbole oder Text) und gibt für jeden Wert describe aus.

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

Probier es selbst

require_relative 'functions'

# Mitgelieferter Ein-/Ausgabe-Code: belasse ihn unverändert
input = []
while (line = gets)
  input << line.chomp
end
def parse(text)
  return Integer(text) if text.match?(/\A-?\d+\z/)
  return Float(text) if text.match?(/\A-?\d+\.\d+\z/)
  return nil if text == "nil"
  return text[1..].to_sym if text.start_with?(":")
  return text[1...-1].split(",").map { |t| parse(t) } if text.start_with?("[")

  text
end

input.each { |line| puts describe(parse(line)) }
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