Latest web development tutorials

Rubyの例外

例外と実行は、常にリンクされています。 あなたが存在しない、と適切な状況を処理しないファイルを開く場合は、あなたのプログラムが低品質であると考えられています。

例外が発生した場合、プログラムが停止します。 そう適切な行動を取るために、プログラムの実行中に発生する可能性がある、とプログラムが完全に停止させませんすべての種類のエラーのための例外処理。

Rubyは例外を処理するための完璧なメカニズムを提供します。 私たちは、例外をスローし、例外の完璧な種類が開始/終了ブロックで処理されるルビーを伝えるために救助句を使用する可能性のあるコードを添付することができます。

文法

begin #开始
 
 raise.. #抛出异常
 
rescue [ExceptionType = StandardException] #捕获指定类型的异常 缺省值是StandardException
 $! #表示异常信息
 $@ #表示异常出现的代码位置
else #其余异常
 ..
ensure #不管有没有异常,进入该代码块
 
end #结束

救助からすべてを開始するに保護されています。 例外が発生したコードブロックの実行中にあれば、制御は終了ブロック救助の間を通過します

以下のためのブロックを各rescue節、Rubyや各パラメータの比較に順番にスローされる例外を開始します。 rescue節は同じ電流によってスローされた例外と例外タイプに名前を付ける、または例外の親クラスである場合、マッチは成功しました。

例外はエラーの指定された型と一致しない場合は、我々はすべてのrescue節の後に他の句を使用することができます。

#!/usr/bin/ruby

begin
   file = open("/unexistant_file")
   if file
      puts "File opened successfully"
   end
rescue
      file = STDIN
end
print file, "==", STDIN, "\n"

上記の出力の例としては、実行されています。 あなたが見ることができるようにオープンに失敗したため、STDIN、ファイルを交換してください。

#<IO:0xb7d16f84>==#<IO:0xb7d16f84>

リトライステートメントを使用します

あなたは、例外をキャッチするために救助ブロックを使用してから、最初から始める始まるリトライステートメントブロックを使用することができます。

文法

begin
    # 这段代码抛出的异常将被下面的 rescue 子句捕获
rescue
    # 这个块将捕获所有类型的异常
    retry  # 这将把控制移到 begin 的开头
end

#!/usr/bin/ruby

begin
   file = open("/unexistant_file")
   if file
      puts "File opened successfully"
   end
rescue
   fname = "existant_file"
   retry
end

以下は、プロセスフローであります:

  • 開いたときに例外が発生しました。
  • 救出にスキップします。 fnameに再割り当てすること。
  • 再試行することから始める先頭にスキップします。
  • ファイルが正常に開かれています。
  • 基本的なプロセスを続行します。

注:名前が変更されたファイルが存在しない場合は、この力コード無制限の試み。だから、例外処理は、注意の再試行を使用しています。

raise文を使用します

あなたはraise文は例外をスローし使用することができます。 以下の方法は、あなたが呼び出す例外をスローします。 その2番目のメッセージが出力されます。

文法

raise 

或

raise "Error Message" 

或

raise ExceptionType, "Error Message"

或

raise ExceptionType, "Error Message" condition

(例外RuntimeErrorを投げされない現在の例外が存在しない場合)最初の形式は、単純に現在の例外を再スローします。 これは、入ってくる例外例外例外ハンドラの前に説明するために使用されます。

2番目の形式は、指定した文字列にそのメッセージを設定し、新しい例外RuntimeError例外を作成します。 コールの後に例外をスローするスタック。

例外を作成するための最初のパラメータの第三形態は、その後、2番目のパラメータとして、関連するメッセージを設定します。

4番目の形式と三番目の形式が似ているが、あなたは例外をスローする(例えばない限り)任意の追加の条件文を追加することができます。

#!/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.'  

上の例の出力は実行します。

I am before the raise.  
I am rescued.  
I am after the begin block.  

別のデモでは、使用例を上げます

#!/usr/bin/ruby

begin  
  raise 'A test exception.'  
rescue Exception => e  
  puts e.message  
  puts e.backtrace.inspect  
end  

上の例の出力は実行します。

A test exception.
["main.rb:4"]

文の使用を確認してください

時には、関係なく、例外がスローされたかどうかの、あなたは、いくつかのプロセスは、コードブロックの最後に完了したことを確認する必要があります。 たとえば、あなたがブロックを終了するとき、あなたはファイルを閉じていることを確認する必要があり、入国時にファイルを開くことがあります。

これで実行する句を確保します 。 最後のrescue節の後に配置され、含まれていることを確認し、ブロック終了コードブロックが常に実行されます。 ブロックを終了投げるとのキャッチされない例外が終了しているためかどうか、これらの関係のいずれもブロックは必ず実行されますを確認していない、かどうかの例外を処理するために正常です。

文法

begin 
   #.. 过程
   #.. 抛出异常
rescue 
   #.. 处理错误 
ensure 
   #.. 最后确保执行
   #.. 这总是会执行
end

begin
  raise 'A test exception.'
rescue Exception => e
  puts e.message
  puts e.backtrace.inspect
ensure
  puts "Ensuring execution"
end

上の例の出力は実行します。

A test exception.
["main.rb:4"]
Ensuring execution

elseステートメントを使用して、

else節が提供されている場合は任意の確保前に、それは通常、rescue後に配置されます。

else節が実行された場合にのみ、例外をスローせずにコードの本体。

文法

begin 
   #.. 过程 
   #.. 抛出异常
rescue 
   #.. 处理错误
else
   #.. 如果没有异常则执行
ensure 
   #.. 最后确保执行
   #.. 这总是会执行
end

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

上の例の出力は実行します。

I'm not raising exception
Congratulations-- no errors!
Ensuring execution

使用$!変数がスローエラーメッセージをキャッチすることができます。

キャッチし、投げます

上げるとエラーが発生したときに救助例外メカニズムが実行をあきらめることができ、時にはあなたは、いくつかの深くネストされた構造物の通常のプロセスにジャンプする必要があります。 この時点キャッチでと重宝投げます。

漁獲量はブロックとして与えられた名前(記号や文字列でもよい)のラベルを定義します。 ブロックは通常、スローに遭遇知って実行されます。

文法

throw :lablename
#.. 这不会被执行
catch :lablename do
#.. 在遇到一个 throw 后匹配将被执行的 catch
end

或

throw :lablename condition
#.. 这不会被执行
catch :lablename do
#.. 在遇到一个 throw 后匹配将被执行的 catch
end

ユーザーのタイプは '!'任意のプロンプトに応答する場合は、次の例では、ユーザとの対話を終了させるためにスローを使用しています。

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:")

上記のプログラムは、人間の相互作用を必要とする、あなたのコンピュータ上で試すことができます。 上の例の出力は実行します。

Name: Ruby on Rails
Age: 3
Sex: !
Name:Just Ruby

例外クラス

Rubyの標準クラスとモジュールがスロー。 すべての例外クラスは、内部例外クラスのトップを含め、階層を形成します。 次の層は7種類です。

  • 割り込み
  • NoMemoryError
  • SignalException
  • ScriptError
  • StandardError
  • SystemExitを

致命的では別の例外の層であるが、Rubyインタプリタは、内部でのみ、それを使用しています。

ScriptErrorとはStandardErrorは、いくつかのサブカテゴリーがありますが、ここではこれらの詳細を知っている必要があります。 最も重要なことは、私たち自身の例外クラスを作成することです、彼らはExceptionクラスまたはその子孫のサブクラスでなければなりません。

例を見てみましょう:

class FileSaveError < StandardError
   attr_reader :reason
   def initialize(reason)
      @reason = reason
   end
end

さて、上記の例外で使用される次の例を見てみましょう。

File.open(path, "w") do |file|
begin
    # 写出数据 ...
rescue
    # 发生错误
    raise FileSaveError.new($!)
end
end

ここでは、最も重要な行はFileSaveError.new($!)を上げています。 私たちは、例外が発生した模式的に上げる呼び出し、それが原因で書き込みに失敗したデータによって引き起こされる特定の異常に新しいインスタンスFileSaveErrorを可決しました。