English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
예외와 실행은 항상 함께 연결됩니다. 파일을 열었는데 파일이 없는 경우 적절히 처리하지 않으면 프로그램은 저질 프로그램으로 간주됩니다.
예외가 발생하면 프로그램이 중지됩니다. 예외는 프로그램 실행 중 발생할 수 있는 여러 유형의 오류를 처리하는 데 사용되며, 따라서 프로그램이 완전히 중지되지 않도록 적절한 조치를 취해야 합니다.
Ruby는 예외를 처리하는 완벽한 메커니즘을 제공합니다. 우리는 begin/end 블록에 예외를 던질 수 있는 코드를 추가하고, rescue 문장은 Ruby가 처리해야 할 예외 유형을 알립니다.
begin #시작 raise #예외를 던집니다 rescue [ExceptionType = StandardException] #지정된 유형의 예외를 잡습니다. 기본 값은 StandardException입니다 $! #예외 정보를 나타냅니다 $@ #예외가 발생한 코드 위치를 나타냅니다 else #기타 예외 ... ensure # 예외가 있与否에 관계없이 이 코드 블록에 진입 end # 끝
로 전달됩니다 begin 로 전달됩니다 rescue 중的一切는 보호됩니다. 코드 블록이 실행 중에 예외가 발생하면, 제어가 rescue 와 end 블록.
사이의 begin 블록의 각 rescue 절에서 예외가 퍼뜨렸습니다. Ruby는 퍼뜨린 예외를 각 매개변수와 순차적으로 비교합니다. 만약 rescue 절에 명명된 예외가 현재 퍼뜨린 예외와 같거나 그 예외의 상위 클래스라면, 일치 성공.
만약 예외가 모든 지정된 오류 유형에 맞지 않으면, 모든 rescue 절 후에 하나를 사용합니다 else 절.
#!/usr/bin/ruby begin file = open("/unexistant_file) if file puts "File opened successfully" end rescue file = STDIN end print file, "==", STDIN, "\n"
위의 예제 실행 결과는 다음과 같습니다. 그리고 볼 수 있습니다STDIN 으로 대체되었습니다. file 은열림실패.
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
이를 사용할 수 있습니다 rescue 블록이 예외를 잡고, 다음과 같이 사용합니다 retry 문장은 처음부터 시작합니다 begin 블록.
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
아래는 처리 과정입니다:
열릴 때 예외가 발생합니다.
rescue로 이동합니다. fname이 다시 할당됩니다.
retry를 통해 begin의 처음으로 이동합니다.
이번에는 파일이 성공적으로 열렸습니다.
기본 과정을 계속합니다.
주의:rename된 파일이 존재하지 않으면, 이 예제 코드는 무한히 시도합니다. 따라서 예외 처리 시 주의하십시오. retry.
이를 사용할 수 있습니다 raise 문장이 예외를 퍼뜨립니다. 호출할 때 예외를 퍼뜨리는 이 메서드는 두 번째 메시지가 출력됩니다.
raise 또는 raise "Error Message" 또는 raise ExceptionType, "Error Message" 또는 raise ExceptionType, "Error Message" condition
첫 번째 형식은 현재 예외를 단순히 다시 퍼뜨립니다. (현재 예외가 없으면 RuntimeError를 퍼뜨립니다). 이는 예외를 설명해야 하는 예외 처리 프로그램에 사용됩니다.
두 번째 형식은 새로운 RuntimeError 예외를 설정하고, 해당 문자열로 메시지를 설정합니다. 이 예외는 호출 스택으로 퍼뜨립니다.
세 번째 형식은 첫 번째 매개변수를 사용하여 예외를 생성하고, 두 번째 매개변수로 관련 메시지를 설정합니다.
네 번째 형식은 세 번째 형식과 유사하며, 추가 조건 문장(예:)} unless를 사용하여 예외를 발생시킵니다。
#!/usr/bin/ruby begin puts '저는 raise 이전입니다.' raise '오류가 발생했습니다.' puts '저는 raise 이전입니다.' rescue puts '저는 구제되었습니다.' end puts '저는 begin 블록 이후입니다.'
위 예제의 실행 결과는 다음과 같습니다:
저는 raise 이전입니다. 저는 구제되었습니다. 저는 begin 블록 이후입니다.
다른 예제 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는 마지막 rescue 문 뒤에 위치하고, 블록이 종료될 때 항상 실행되는 코드 블록을 포함합니다. 블록이 정상적으로 종료되었는지, 예외를 발생시키고 처리했는지, 미취약한 예외로 인해 종료되었는지에 관계없이 실행됩니다.ensure 블록은 항상 실행됩니다。
begin #.. 과정 #.. 예외를 발생시킵니다 rescue #.. 오류를 처리합니다 ensure #.. 마지막으로 실행을 보장합니다 #.. 이는 항상 실행됩니다 end
begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts "execution을 보장하십시오" end
위 예제의 실행 결과는 다음과 같습니다:
A test exception. ["main.rb:4"] execution을 보장하십시오
제공되면 else ensure 문장은 일반적으로 rescue ensure 문 이후, 어떤 문장이든 ensure 이전.
else ensure 문은 코드 본문이 예외를 발생시키지 않았을 때만 실행되는 문장의 주체입니다.
begin #.. 과정 #.. 예외를 발생시킵니다 rescue #.. 오류를 처리합니다 else #.. 예외가 없으면 실행됩니다 ensure #.. 마지막으로 실행을 보장합니다 #.. 이는 항상 실행됩니다 end
begin # 'A test exception.'를 발생시키십시오 puts "저는 예외를 발생시키지 않습니다" rescue Exception => e puts e.message puts e.backtrace.inspect else puts "축하합니다"-- 에러가 없습니다" ensure puts "execution을 보장하십시오" end
위 예제의 실행 결과는 다음과 같습니다:
异常을 발생시키지 않습니다 축하합니다-- 에러가 없습니다! execution을 보장하십시오
$! 변수를 사용하여 투げ쳐진 오류 메시지를 캡처할 수 있습니다.
raise와 rescue의 예외 메커니즘은 오류가 발생할 때 실행을 포기할 수 있으며, 때로는 정상 처리 중에 깊은 내부 구조에서 벗어나야 할 때 있습니다. 이때 catch와 throw이 유용하게 사용됩니다.
catch 이는 주어진 이름(시μβ올이나 문자열이 될 수 있습니다)을 태그로 사용하는 블록을 정의합니다. 블록은 throw에 도달할 때까지 정상적으로 실행됩니다.
throw :lablename #.. 이는 실행되지 않습니다. catch :lablename do #.. throw이 발생한 후에 catch와 일치하는 것을 찾습니다. end 또는 throw :lablename condition #.. 이는 실행되지 않습니다. catch :lablename do #.. throw이 발생한 후에 catch와 일치하는 것을 찾습니다. end
아래의 예제에서 사용자가 어떤 제안에 대해 '!'을 입력하면 throw을 사용하여 사용자와의 상호작용을 종료합니다.
def promptAndGet(prompt) print prompt res = readline.chomp res == "!"면 throw :quitRequested 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의 표준 클래스와 모듈은 예외를 투げ치며. 모든 예외 클래스는 최상위 Exception 클래스를 포함하여 계층을 구성합니다. 다음 계층은 일곱 가지 다른 유형이 있습니다:
Interrupt
NoMemoryError
SignalException
ScriptError
StandardError
SystemExit
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의 새로운 예제에 전달하여 특정한 예외로 인해 데이터 쓰기 실패가 발생했습니다.