Lever une exception, c'est envoyer un objet vers le haut de la pile.Raising an exception is sending an object up the stack.
Le Vol 7 ouvre le flux d'erreur. Et fidèle au fil de la série, une exception n'est pas une construction à part : c'est un objet (Vol 1), instance d'une classe d'erreur, qu'on lève et qu'on rattrape par son type. raise crée et propulse cet objet vers le haut de la pile d'appels, en déroulant chaque méthode au passage, jusqu'à ce qu'un rescue du bon type l'attrape. ensure, lui, garantit qu'un bout de code s'exécute quoi qu'il arrive — succès ou erreur. Trois mots, trois rôles : signaler, rattraper, nettoyer. Tout le mécanisme tient là.Vol 7 opens the error flow. And true to the series' thread, an exception isn't a separate construct: it's an object (Vol 1), an instance of an error class, raised and caught by its type. raise creates and propels that object up the call stack, unwinding each method along the way, until a rescue of the right type catches it. ensure guarantees a piece of code runs whatever happens — success or error. Three words, three roles: signal, catch, clean up. The whole mechanism sits there.
# une exception est un OBJET, levé puis rattrapé par sa CLASSE err = ArgumentError.new("âge négatif") err.is_a?(StandardError) # => true c'est un objet, dans une hiérarchie err.message # => "âge négatif" def set_age(n) raise ArgumentError, "âge négatif" if n < 0 # lever : on signale @age = n end begin set_age(-1) rescue ArgumentError => e # rattraper PAR TYPE puts "refusé : #{e.message}" ensure puts "toujours exécuté" # nettoyer : quoi qu'il arrive end
L'objet-erreur déroule la pile : chaque méthode traversée est abandonnée jusqu'à ce qu'un rescue du bon type l'attrape. Si aucun ne l'attrape, il atteint le sommet et le programme s'arrête. ensure court à chaque niveau traversé.The error object unwinds the stack: each method crossed is abandoned until a rescue of the right type catches it. If none does, it reaches the top and the program halts. ensure runs at every level crossed.
« Est-ce une condition vraiment exceptionnelle (raise), ou un flux normal déguisé en erreur ? » Avant de lever, demande-toi si le cas est anormal — une donnée invalide, un état impossible — ou simplement un résultat attendu (clé absente, fin de fichier) qu'une valeur de retour exprimerait mieux."Is this a truly exceptional condition (raise), or normal flow disguised as an error?" Before raising, ask whether the case is abnormal — invalid data, an impossible state — or just an expected outcome (missing key, end of file) a return value would express better.
Comme tout en Ruby. raise lève une instance d'une classe d'erreur ; rescue la rattrape en testant sa classe (le duck typing des erreurs, № 2). e.message, e.backtrace sont des messages envoyés à cet objet. Comprendre ça désamorce toute la « magie » : il n'y a pas de système d'exception à part, juste des objets qu'on lève et qu'on trie par type le long de la pile.Like everything in Ruby. raise raises an instance of an error class; rescue catches it by testing its class (the duck typing of errors, № 2). e.message, e.backtrace are messages sent to that object. Grasping this defuses all the 'magic': there's no separate exception system, just objects you raise and sort by type along the stack.