_ruby異常
8058 ワード
Ruby異常
例外と実行は常に関連付けられています.存在しないファイルを開き、適切に処理していない場合は、プログラムは低品質とみなされます.
異常が発生した場合、プログラムは停止します.例外は、プログラムの実行中に発生する可能性のあるさまざまなタイプのエラーを処理するために使用されます.プログラムを完全に停止させることなく、適切な行動を取らなければなりません.
Rubyは異常を完璧に処理するメカニズムを提供した.begin/endブロックに異常を投げ出す可能性のあるコードを添付し,rescue句を用いてRubyに処理すべき異常タイプを完全に伝えることができる.
構文
beginからrescueまでのすべては保護されています.コードブロックの実行中に異常が発生した場合、制御はrescueとendの間のブロックに渡されます.
beginブロック内の各rescue句について,Rubyは投げた異常を各パラメータと交互に比較した.rescue句に名前が付けられている例外が、現在投げ出されている例外タイプと同じか、またはその例外の親である場合、一致は成功します.
例外が指定したすべてのエラー・タイプに一致しない場合は、すべてのrescue句の後にelse句を使用できます.
≪インスタンス|Instance|emdw≫
これにより、以下の結果が得られます.開くのに失敗したため、stdINがfileに取って代わったことがわかります.
retry文の使用
rescueブロックを使用して例外をキャプチャし、retry文を使用して最初からbeginブロックを実行できます.
構文
≪インスタンス|Instance|emdw≫
次の処理手順を示します.が開いている間に異常が発生しました. rescueにジャンプします.fnameは再割り当てされます. retryを介してbeginの先頭にジャンプします. 今回のファイルは正常に開きました. は基本的なプロセスを継続します.
注意:再命名されたファイルが存在しない場合、本勢力コードは無限に試みられます.異常処理の場合はretryを慎重に使用します.
raise文の使用
raise文を使用して例外を放出できます.次の方法では、呼び出し時に例外を放出します.2番目のメッセージが出力されます.
構文
第1の形態は、現在の異常を単純に再放出する(現在の異常がなければRuntimeErrorを放出する).これは、異常が入力される前に異常を説明する必要がある異常ハンドラで使用されます.
2つ目の形式は、指定された文字列にメッセージを設定する新しいRuntimeError例外を作成します.この例外は、呼び出しスタックに放出されます.
第3の形式では、第1のパラメータを使用して例外を作成し、関連するメッセージを第2のパラメータに設定します.
4番目の形式は3番目の形式と似ています.unlessなどの追加の条件文を追加して例外を投げ出すことができます.
≪インスタンス|Instance|emdw≫
これにより、次の結果が得られます.
もう1つのraiseの使用例を示します.
これにより、次の結果が得られます.
ensure文の使用
例外を投げ出すかどうかにかかわらず、コードブロックの終了時にいくつかの処理が完了することを保証する必要があります.たとえば、ブロックを終了するときにファイルを開く場合は、ファイルを閉じる必要があります.
ensure句が作ったのはこれです.Ensureは最後のrescue句の後に配置され、ブロック終了時に常に実行されるコードブロックが含まれます.ブロックが正常に終了しているかどうか、例外を放出して処理しているかどうか、取得されていない例外によって終了しているかどうかは関係ありません.ensureブロックは常に実行されます.
構文
≪インスタンス|Instance|emdw≫
これにより、次の結果が得られます.
else文の使用
else句が提供される場合、通常はrescue句の後、任意のensureの前に配置されます.
else句の主体は,コード主体が異常を投げ出さなかった場合にのみ実行される.
構文
≪インスタンス|Instance|emdw≫
これにより、次の結果が得られます.
$を使用!変数は、投げ出されたエラーメッセージをキャプチャします.
CatchとThrow
raiseとrescueの異常メカニズムは、エラーが発生したときに実行を放棄することができ、通常の処理時に深いネストされた構造から飛び出す必要がある場合があります.このときcatchとthrowが役に立ちます.
catchは、指定された名前(SymbolまたはString)をラベルとして使用するブロックを定義します.ブロックは正常に実行され、throwに遭遇したことを知っています.
構文
≪インスタンス|Instance|emdw≫
次の例では、ユーザーが「!任意のプロンプトに応答して、throwを使用してユーザーとのインタラクションを終了します.
上記のプログラムは人工的なインタラクションが必要で、コンピュータで試してみることができます.これにより、次の結果が得られます.
クラスException
Rubyの標準クラスとモジュールから例外が放出されます.すべての例外クラスは、上部のExceptionクラスを含む階層を構成します.次の階層は7つの異なるタイプです. Interrupt NoMemoryError SignalException ScriptError StandardError SystemExit
Fatalはこの層のもう一つの異常であるが,Ruby解釈器は内部でのみ使用される.
ScriptErrorとStandardErrorにはいくつかのサブクラスがありますが、ここではこれらの詳細を理解する必要はありません.最も重要なことは、クラスExceptionまたはその子のサブクラスである必要がある独自の例外クラスを作成することです.
例を見てみましょう.
次に、次の例を見て、上記の例外を使用します.
ここで最も重要な行はraise FileSaveErrorですnew($!).私たちはraiseを呼び出して異常が発生したことを示し、それをFileSaveErrorの新しいインスタンスに伝え、特定の異常によってデータの書き込みに失敗した.
例外と実行は常に関連付けられています.存在しないファイルを開き、適切に処理していない場合は、プログラムは低品質とみなされます.
異常が発生した場合、プログラムは停止します.例外は、プログラムの実行中に発生する可能性のあるさまざまなタイプのエラーを処理するために使用されます.プログラムを完全に停止させることなく、適切な行動を取らなければなりません.
Rubyは異常を完璧に処理するメカニズムを提供した.begin/endブロックに異常を投げ出す可能性のあるコードを添付し,rescue句を用いてRubyに処理すべき異常タイプを完全に伝えることができる.
構文
begin
# -
rescue OneTypeOfException
# -
rescue AnotherTypeOfException
# -
else
#
ensure
#
end
beginからrescueまでのすべては保護されています.コードブロックの実行中に異常が発生した場合、制御はrescueとendの間のブロックに渡されます.
beginブロック内の各rescue句について,Rubyは投げた異常を各パラメータと交互に比較した.rescue句に名前が付けられている例外が、現在投げ出されている例外タイプと同じか、またはその例外の親である場合、一致は成功します.
例外が指定したすべてのエラー・タイプに一致しない場合は、すべてのrescue句の後にelse句を使用できます.
≪インスタンス|Instance|emdw≫
#!/usr/bin/ruby
begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
file = STDIN
end
print file, "==", STDIN, "
"
これにより、以下の結果が得られます.開くのに失敗したため、stdINがfileに取って代わったことがわかります.
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
retry文の使用
rescueブロックを使用して例外をキャプチャし、retry文を使用して最初からbeginブロックを実行できます.
構文
begin
# rescue
rescue
#
retry # begin
end
≪インスタンス|Instance|emdw≫
#!/usr/bin/ruby
begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
fname = "existant_file"
retry
end
次の処理手順を示します.
注意:再命名されたファイルが存在しない場合、本勢力コードは無限に試みられます.異常処理の場合はretryを慎重に使用します.
raise文の使用
raise文を使用して例外を放出できます.次の方法では、呼び出し時に例外を放出します.2番目のメッセージが出力されます.
構文
raise
OR
raise "Error Message"
OR
raise ExceptionType, "Error Message"
OR
raise ExceptionType, "Error Message" condition
第1の形態は、現在の異常を単純に再放出する(現在の異常がなければRuntimeErrorを放出する).これは、異常が入力される前に異常を説明する必要がある異常ハンドラで使用されます.
2つ目の形式は、指定された文字列にメッセージを設定する新しいRuntimeError例外を作成します.この例外は、呼び出しスタックに放出されます.
第3の形式では、第1のパラメータを使用して例外を作成し、関連するメッセージを第2のパラメータに設定します.
4番目の形式は3番目の形式と似ています.unlessなどの追加の条件文を追加して例外を投げ出すことができます.
≪インスタンス|Instance|emdw≫
#!/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.
もう1つのraiseの使用例を示します.
#!/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"]
ensure文の使用
例外を投げ出すかどうかにかかわらず、コードブロックの終了時にいくつかの処理が完了することを保証する必要があります.たとえば、ブロックを終了するときにファイルを開く場合は、ファイルを閉じる必要があります.
ensure句が作ったのはこれです.Ensureは最後のrescue句の後に配置され、ブロック終了時に常に実行されるコードブロックが含まれます.ブロックが正常に終了しているかどうか、例外を放出して処理しているかどうか、取得されていない例外によって終了しているかどうかは関係ありません.ensureブロックは常に実行されます.
構文
begin
#..
#..
rescue
#..
ensure
#..
#..
end
≪インスタンス|Instance|emdw≫
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句の後、任意のensureの前に配置されます.
else句の主体は,コード主体が異常を投げ出さなかった場合にのみ実行される.
構文
begin
#..
#..
rescue
#..
else
#..
ensure
#..
#..
end
≪インスタンス|Instance|emdw≫
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
$を使用!変数は、投げ出されたエラーメッセージをキャプチャします.
CatchとThrow
raiseとrescueの異常メカニズムは、エラーが発生したときに実行を放棄することができ、通常の処理時に深いネストされた構造から飛び出す必要がある場合があります.このときcatchとthrowが役に立ちます.
catchは、指定された名前(SymbolまたはString)をラベルとして使用するブロックを定義します.ブロックは正常に実行され、throwに遭遇したことを知っています.
構文
throw :lablename
#..
catch :lablename do
#.. throw catch
end
OR
throw :lablename condition
#..
catch :lablename do
#.. throw catch
end
≪インスタンス|Instance|emdw≫
次の例では、ユーザーが「!任意のプロンプトに応答して、throwを使用してユーザーとのインタラクションを終了します.
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
クラスException
Rubyの標準クラスとモジュールから例外が放出されます.すべての例外クラスは、上部のExceptionクラスを含む階層を構成します.次の階層は7つの異なるタイプです.
Fatalはこの層のもう一つの異常であるが,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
ここで最も重要な行はraise FileSaveErrorですnew($!).私たちはraiseを呼び出して異常が発生したことを示し、それをFileSaveErrorの新しいインスタンスに伝え、特定の異常によってデータの書き込みに失敗した.