Menu
Coddy logo textTech

Cas et classes

Fait partie de la section Programmation orientée objet du Journey Ruby de Coddy. Leçon 35 sur 57.

case peut effectuer une sélection selon la classe d’une valeur. when Integer correspond à chaque entier, car case compare avec ===, et Integer === 5 demande si 5 est un Integer (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) }

Résultat :

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

Comme === sur une classe suit is_a?, un when avec une superclasse correspond également à ses sous-classes. Ordonne les branches de la classe la plus spécifique à la plus générale :

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

Sortie :

a dog
some animal
not an animal
true

Un when peut répertorier plusieurs classes, et les branches peuvent effectuer un véritable traitement sur la valeur, comme totaliser une structure imbriquée de types mixtes :

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] }])

Résultat :

10.5

Le branchement selon les classes convient aux valeurs auxquelles vous ne pouvez pas ajouter de nouvelles méthodes, comme les nombres, les chaînes et les tableaux, ou aux données provenant de l'extérieur. Pour vos propres classes, préférez le polymorphisme : une nouvelle classe nécessite alors une nouvelle méthode, et non une nouvelle branche dans chaque case :

# vos propres classes : laissez chacune répondre
shape.area

# valeurs intégrées de l'extérieur : branchez sur la classe
case value
when Integer then ...
when String then ...
end
challenge icon

Défi

Facile

Complète l’assistant describe(value) dans functions.rb avec un case sur la classe de la valeur. Il renvoie integer 5 (odd) ou integer 4 (even), float 2.50 avec deux décimales, text "hi" (2 chars), list of 3: 1, a, 2.5 (les éléments joints avec to_s), nothing pour nil et other Symbol pour toute autre valeur. Les symboles sont le seul autre type présent dans les tests.

Le code fourni transforme chaque ligne d’entrée en une valeur (nombres entiers, nombres décimaux, listes [a,b], nil, symboles :name ou texte) et affiche describe pour chacune.

Ton code doit être placé dans functions.rb. main.rb contient le code fourni pour les entrées et les sorties et ne peut pas être modifié.

Essayez vous-même

require_relative 'functions'

# Code d'entrée/sortie fourni : le garder tel quel
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 iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation orientée objet

Entraînez-vous par vous-même : Compilateur Ruby en ligne