Ruby Language
시작 / 복구로 예외 잡기
수색…
기본 오류 처리 블록
두 숫자를 나눌 함수를 만들자. 입력에 대해 매우 신뢰하고있다.
def divide(x, y)
return x/y
end
이것은 많은 입력에 대해 잘 작동합니다.
> puts divide(10, 2)
5
전부는 아니지만
> puts divide(10, 0)
ZeroDivisionError: divided by 0
> puts divide(10, 'a')
TypeError: String can't be coerced into Fixnum
begin... end
블록에서 위험한 나누기 연산을 래핑하여 오류를 검사하고 rescue
절을 사용하여 메시지를 출력하고 문제가있는 경우 nil
반환하여 함수를 다시 작성할 수 있습니다.
def divide(x, y)
begin
return x/y
rescue
puts "There was an error"
return nil
end
end
> puts divide(10, 0)
There was an error
> puts divide(10, 'a')
There was an error
오류 저장
rescue
절에서 오류를 사용하려면 오류를 저장할 수 있습니다.
def divide(x, y)
begin
x/y
rescue => e
puts "There was a %s (%s)" % [e.class, e.message]
puts e.backtrace
end
end
> divide(10, 0)
There was a ZeroDivisionError (divided by 0)
from (irb):10:in `/'
from (irb):10
from /Users/username/.rbenv/versions/2.3.1/bin/irb:11:in `<main>'
> divide(10, 'a')
There was a TypeError (String can't be coerced into Fixnum)
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87:in `eval'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/workspace.rb:87:in `evaluate'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/context.rb:380:in `evaluate'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:489:in `block (2 levels) in eval_input'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:623:in `signal_status'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:486:in `block in eval_input'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/ruby-lex.rb:246:in `block (2 levels) in each_top_level_statement'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/ruby-lex.rb:232:in `loop'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/ruby-lex.rb:232:in `block in each_top_level_statement'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/ruby-lex.rb:231:in `catch'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb/ruby-lex.rb:231:in `each_top_level_statement'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:485:in `eval_input'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:395:in `block in start'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:394:in `catch'
/Users/username/.rbenv/versions/2.3.1/lib/ruby/2.3.0/irb.rb:394:in `start'
/Users/username/.rbenv/versions/2.3.1/bin/irb:11:in `<main>'
다른 오류 확인하기
오류의 종류에 따라 다른 작업을 수행하려면 각각 다른 오류 유형의 인수로 여러 rescue
사용하십시오.
def divide(x, y)
begin
return x/y
rescue ZeroDivisionError
puts "Don't divide by zero!"
return nil
rescue TypeError
puts "Division only works on numbers!"
return nil
end
end
> divide(10, 0)
Don't divide by zero!
> divide(10, 'a')
Division only works on numbers!
rescue
블록에서 사용하기 위해 오류를 저장하려면 다음을 수행하십시오.
rescue ZeroDivisionError => e
다른 rescue
절에 지정되지 않은 유형의 오류를 catch하려면 인수없이 rescue
절을 사용하십시오.
def divide(x, y)
begin
return x/y
rescue ZeroDivisionError
puts "Don't divide by zero!"
return nil
rescue TypeError
puts "Division only works on numbers!"
return nil
rescue => e
puts "Don't do that (%s)" % [e.class]
return nil
end
end
> divide(nil, 2)
Don't do that (NoMethodError)
이 경우 nil
을 2로 나눌 때는 ZeroDivisionError
또는 TypeError
가 아니므로 기본 rescue
절에 의해 처리됩니다.이 rescue
절은 NoMethodError
임을 알리는 메시지를 출력합니다.
재 시도 중
rescue
절에서 retry
를 사용하여 오류를 일으킨 상황을 변경 한 후 begin
절을 다시 실행할 수 있습니다.
def divide(x, y)
begin
puts "About to divide..."
return x/y
rescue ZeroDivisionError
puts "Don't divide by zero!"
y = 1
retry
rescue TypeError
puts "Division only works on numbers!"
return nil
rescue => e
puts "Don't do that (%s)" % [e.class]
return nil
end
end
TypeError
가 발생하는 것으로 TypeError
매개 변수를 전달하면 begin
절이 실행되고 ( "약 나누기"를 인쇄하여 여기에 플래그가 TypeError
) 오류가 이전과 같이 catch되고 nil
이 반환됩니다.
> divide(10, 'a')
About to divide...
Division only works on numbers!
=> nil
그러나 ZeroDivisionError
를 유발할 매개 변수를 전달하면 begin
절이 실행되고 오류가 감지되고 제수가 0에서 1로 변경된 다음 retry
하면 begin
블록이 다시 실행됩니다 (위에서부터). 다른 y
. 두 번째로는 오류가 없으며 함수는 값을 반환합니다.
> divide(10, 0)
About to divide... # First time, 10 ÷ 0
Don't divide by zero!
About to divide... # Second time 10 ÷ 1
=> 10
오류 발생 여부 확인
에러가 발생하지 않으면 실행될 코드에 else
절을 사용할 수 있습니다.
def divide(x, y)
begin
z = x/y
rescue ZeroDivisionError
puts "Don't divide by zero!"
rescue TypeError
puts "Division only works on numbers!"
return nil
rescue => e
puts "Don't do that (%s)" % [e.class]
return nil
else
puts "This code will run if there is no error."
return z
end
end
제어를 rescue
절 중 하나로 전달하는 오류가있는 경우 else
절은 실행되지 않습니다.
> divide(10,0)
Don't divide by zero!
=> nil
그러나 오류가 발생하지 else
절이 실행됩니다.
> divide(10,2)
This code will run if there is no error.
=> 5
begin
절에서 돌아 오면 else
절은 실행되지 않습니다.
def divide(x, y)
begin
z = x/y
return z # Will keep the else clause from running!
rescue ZeroDivisionError
puts "Don't divide by zero!"
else
puts "This code will run if there is no error."
return z
end
end
> divide(10,2)
=> 5
항상 실행해야하는 코드
항상 실행하려는 코드가있는 경우, ensure
절을 사용하십시오.
def divide(x, y)
begin
z = x/y
return z
rescue ZeroDivisionError
puts "Don't divide by zero!"
rescue TypeError
puts "Division only works on numbers!"
return nil
rescue => e
puts "Don't do that (%s)" % [e.class]
return nil
ensure
puts "This code ALWAYS runs."
end
end
오류가있을 때 ensure
절이 실행됩니다.
> divide(10, 0)
Don't divide by zero! # rescue clause
This code ALWAYS runs. # ensure clause
=> nil
그리고 오류가없는 경우 :
> divide(10, 2)
This code ALWAYS runs. # ensure clause
=> 5
확실한 절은 파일이 닫혀 있는지 확인하고자 할 때 유용합니다.
else
절과 달리 ensure
절 은 begin
또는 rescue
절이 값을 반환하기 전에 실행 begin
. 는 IF ensure
절은이 return
무시됩니다 return
다른 조항의 가치를!