Exception rubis
Les exceptions et l'exécution sont toujours liées. Si vous ouvrez un fichier qui n'existe pas et ne gérez pas la situation de manière appropriée, votre programme est considéré comme de mauvaise qualité.
Si une exception se produit, le programme s'arrête. Les exceptions sont utilisées pour gérer différents types d'erreurs pouvant survenir lors de l'exécution du programme, afin que les mesures appropriées soient prises sans arrêter complètement le programme.
Ruby fournit un mécanisme parfait pour gérer les exceptions. Nous pouvons enfermer le code qui peut lever une exception dans un bloc begin/end et utiliser la clause rescue pour indiquer à Ruby quel type d'exception gérer.
Syntaxe
begin #开始 raise.. #抛出异常 rescue [ExceptionType = StandardException] #捕获指定类型的异常 缺省值是StandardException $! #表示异常信息 $@ #表示异常出现的代码位置 else #其余异常 .. ensure #不管有没有异常,进入该代码块 end #结束
Tout, du début au sauvetage est protégé. Si une exception se produit lors de l'exécution d'un bloc de code, le contrôle est passé au bloc entre rescue et end.
Pour chaque clause rescue du bloc begin, Ruby compare l'exception levée avec chaque argument tour à tour. Si l'exception nommée dans la clause de sauvetage est du même type que l'exception actuellement levée ou est la classe parent de l'exception, la correspondance réussit.
Si l'exception ne correspond pas à tous les types d'erreurs spécifiés, nous pouvons utiliser une clause else après toutes les clauses rescue.
Exemple
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue file = STDIN end print file, "==", STDIN, "\n"
Le résultat de sortie de l'exemple ci-dessus est. Vous pouvez voir que STDIN remplace le fichier car ne parvient pas à ouvrir .
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
Utilisez l'instruction retry
Vous pouvez utiliser le bloc rescue pour intercepter l'exception, puis utiliser l'instruction retry pour démarrer exécution depuis le début du bloc begin.
Syntaxe
begin # 这段代码抛出的异常将被下面的 rescue 子句捕获 rescue # 这个块将捕获所有类型的异常 retry # 这将把控制移到 begin 的开头 end
Instance
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue fname = "existant_file" retry end
Voici le flux de traitement :
Une exception s'est produite lors de l'ouverture.
Sauter à la rescousse. fname est réaffecté.
Sauter au début du début en réessayant.
Cette fois, le fichier a été ouvert avec succès.
Continuez avec le processus de base.
Remarque : Si le fichier renommé n'existe pas, le code de cette force essaiera à l'infini. Par conséquent, utilisez retry avec prudence lors de la gestion des exceptions.
Utilisation de l'instruction raise
Vous pouvez utiliser l'instruction raise pour lever une exception. La méthode suivante lève une exception lorsqu'elle est appelée. Son deuxième message sera émis.
Syntaxe
raise 或 raise "Error Message" 或 raise ExceptionType, "Error Message" 或 raise ExceptionType, "Error Message" condition
Le premier formulaire renvoie simplement l'exception actuelle (ou une RuntimeError s'il n'y a pas d'exception actuelle). Ceci est utilisé dans les gestionnaires d'exceptions qui doivent interpréter l'exception avant de la transmettre.
Le deuxième formulaire crée une nouvelle exception RuntimeError, définissant son message sur la chaîne donnée. L'exception est ensuite générée dans la pile d'appels.
Le troisième formulaire crée une exception en utilisant le premier paramètre, puis définit le message associé comme deuxième paramètre.
Le quatrième formulaire est similaire au troisième formulaire, vous pouvez ajouter des instructions conditionnelles supplémentaires (telles que sauf si) pour lever une exception.
Instance
#!/usr/bin/ruby begin puts 'I am before the raise.' raise 'An error has occurred.' puts 'I am after the raise.' rescue puts 'I am rescued.' end puts 'I am after the begin block.'
L'exemple ci-dessus d'exécution du résultat de sortie est :
I am before the raise. I am rescued. I am after the begin block.
Un autre exemple démontrant l'utilisation de raise :
#!/usr/bin/ruby begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect end
ci-dessus Le résultat de sortie de l'instance en cours d'exécution est :
A test exception. ["main.rb:4"]
Utilisez l'instruction ensure
Parfois, qu'une exception soit levée ou non, vous devez vous assurer que certains traitements est terminé à la fin du bloc de code. Par exemple, vous pouvez avoir un fichier ouvert lorsque vous entrez et lorsque vous quittez le bloc, vous devez vous assurer de fermer le fichier.
C'est exactement ce que fait la clauseassurer. assurer est placé après la dernière clause de sauvetage et contient un bloc de code qui est toujours exécuté à la fin du bloc. Peu importe que le bloc se termine correctement, qu'il lève et gère une exception ou qu'il se termine par une exception non interceptée, le bloc ensure sera toujours exécuté.
Syntaxe
begin #.. 过程 #.. 抛出异常 rescue #.. 处理错误 ensure #.. 最后确保执行 #.. 这总是会执行 end
Exemple
begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts "Ensuring execution" end
Le résultat de l'exemple ci-dessus est :
A test exception. ["main.rb:4"] Ensuring execution
Utilisez l'instruction else
Si la clause else est fournie, elle est généralement placée après la clause rescue et avant tout ensure. Le corps de la clause
else n'est exécuté que si le corps du code ne lève pas d'exception.
Syntaxe
begin #.. 过程 #.. 抛出异常 rescue #.. 处理错误 else #.. 如果没有异常则执行 ensure #.. 最后确保执行 #.. 这总是会执行 end
Exemple
begin # 抛出 'A test exception.' puts "I'm not raising exception" rescue Exception => e puts e.message puts e.backtrace.inspect else puts "Congratulations-- no errors!" ensure puts "Ensuring execution" end
Le résultat de l'exemple ci-dessus est :
I'm not raising exception Congratulations-- no errors! Ensuring execution
Utilisez la variable $! Le mécanisme d'exception de
Catch and Throw
raise and Rescue peut abandonner l'exécution lorsqu'une erreur se produit. Parfois, il est nécessaire de sortir de certaines structures profondément imbriquées pendant le traitement normal. C’est là que attraper et lancer s’avère utile.
catch définit un bloc qui utilise le nom donné (qui peut être un symbole ou une chaîne) comme étiquette. Le bloc s'exécutera normalement jusqu'à ce qu'un lancer soit rencontré.
Syntaxe
throw :lablename #.. 这不会被执行 catch :lablename do #.. 在遇到一个 throw 后匹配将被执行的 catch end 或 throw :lablename condition #.. 这不会被执行 catch :lablename do #.. 在遇到一个 throw 后匹配将被执行的 catch end
Exemples
Dans l'exemple suivant, si l'utilisateur tape '!' en réponse à une invite, un lancer est utilisé pour mettre fin à l'interaction avec l'utilisateur .
def promptAndGet(prompt) print prompt res = readline.chomp throw :quitRequested if res == "!" return res end catch :quitRequested do name = promptAndGet("Name: ") age = promptAndGet("Age: ") sex = promptAndGet("Sex: ") # .. # 处理信息 end promptAndGet("Name:")
Le programme ci-dessus nécessite une interaction humaine, vous pouvez l'essayer sur votre ordinateur. Le résultat de sortie de l'exemple ci-dessus est :
Name: Ruby on Rails Age: 3 Sex: ! Name:Just Ruby
Class Exception
Les classes et modules standard de Ruby lèvent des exceptions. Toutes les classes d'exception forment une hiérarchie, y compris la classe Exception en haut. Le niveau suivant comprend sept types différents :
Interrupt
NoMemoryError
SignalException
ScriptError
StandardError
SystemExit
Fatal est une autre exception dans cette couche, mais l'interpréteur Ruby ne l'utilise qu'en interne.
ScriptError et StandardError ont toutes deux des sous-classes, mais nous n'avons pas besoin de connaître ces détails ici. Le plus important est de créer nos propres classes d'exception, elles doivent être des sous-classes de la classe Exception ou de ses descendants.
Voyons un exemple :
class FileSaveError < StandardError attr_reader :reason def initialize(reason) @reason = reason end end
Maintenant, regardez l'exemple suivant où l'exception ci-dessus sera utilisée :
File.open(path, "w") do |file| begin # 写出数据 ... rescue # 发生错误 raise FileSaveError.new($!) end end
Ici, la ligne la plus importante est raise FileSaveError.new($!). Nous appelons raise pour indiquer qu'une exception s'est produite, en la transmettant à une nouvelle instance de FileSaveError qui n'a pas réussi à écrire des données en raison de l'exception spécifique.