Menu
CoddyTech

Fälle und Klassen

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

case kann je nach Klasse eines Werts verzweigen. when Integer trifft auf jede Ganzzahl zu, weil case mit === vergleicht und Integer === 5 fragt, 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 auf deren Unterklassen zu. Ordne die Zweige von der spezifischsten zur allgemeinsten Klasse:

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 leisten, zum Beispiel eine verschachtelte Struktur mit gemischten Typen 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

Verzweigungen nach Klassen eignen sich für Werte, deren Klassen du keine neuen Methoden geben kannst, etwa Zahlen, Zeichenketten und Arrays oder Daten von außerhalb. Für deine eigenen Klassen solltest du Polymorphismus bevorzugen: Eine neue Klasse benötigt dann eine neue Methode und keine neue Verzweigung in jedem case:

# Eigene Klassen: Lass jede selbst antworten
shape.area

# Eingebaute Werte von außen: Verzweige je nach Klasse
case value
when Integer then ...
when String then ...
end
challenge icon

Aufgabe

Einfach

Vervollständige den Hilfsfunktion describe(value) in functions.rb mit einem case auf die Klasse des Werts. Sie 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 Elemente, mit to_s verbunden), nothing für nil und other Symbol für alles andere zurück. In den Tests kommen als einzige weitere Art Symbole vor.

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 kommt in functions.rb. main.rb enthält den bereitgestellten Ein-/Ausgabecode und darf nicht bearbeitet werden.

Probier es selbst

require_relative 'functions'

# Vorgegebener Eingabe-/Ausgabecode: unverändert lassen
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