Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Rubys 예외 대 StandardError:차이점은 무엇입니까?

"Ruby에서 예외를 절대 구하지 마세요!"

아마도 당신은 전에 이것을 들어본 적이 있을 것입니다. 좋은 조언이지만 이미 알고 있지 않는 한 꽤 혼란스럽습니다. 이 문장을 분해하여 의미를 알아보겠습니다.

Ruby에서 다음과 같은 예외를 구할 수 있다는 것을 알고 있을 것입니다.

begin
  do_something()
rescue => e
  puts e # e is an exception object containing info about the error. 
end

그리고 오류의 클래스 이름을 제공하여 특정 오류를 복구할 수 있습니다.

begin
  do_something()
rescue ActiveRecord::RecordNotFound => e
  puts e # Only rescues RecordNotFound exceptions, or classes that inherit from RecordNotFound
end

Ruby의 모든 유형의 예외는 클래스일 뿐입니다. 위의 예에서 ActiveRecord::RecordNotFound는 특정 규칙을 따르는 클래스의 이름일 뿐입니다.

이것은 RecordNotFound를 구출할 때 중요합니다. , 당신은 또한 그것에서 상속되는 모든 예외를 구출합니다.

예외를 구하면 안 되는 이유

Exception 구출 문제 Exception에서 상속되는 모든 예외를 실제로 구한다는 것입니다. . 그게...다들입니다!

Ruby에서 내부적으로 사용하는 몇 가지 예외가 있기 때문에 문제입니다. 그들은 당신의 앱과 아무 관련이 없으며 삼키면 나쁜 일이 일어납니다.

다음은 몇 가지 중요한 사항입니다.

  • SignalException::인터럽트 - 이것을 구하면 control-c를 눌러 앱을 종료할 수 없습니다.

  • ScriptError::SyntaxError - 구문 오류를 삼키는 것은 puts("Forgot something)과 같은 것을 의미합니다. 자동으로 실패합니다.

  • 메모리 오류 없음 - 프로그램이 RAM을 모두 사용한 후에도 프로그램이 계속 실행되면 어떻게 되는지 알고 싶으십니까? 저도 마찬가지입니다.

begin
  do_something()
rescue Exception => e
  # Don't do this. This will swallow every single exception. Nothing gets past it. 
end

나는 당신이 정말로 이러한 시스템 수준 예외를 삼키고 싶지 않다고 생각합니다. 모든 애플리케이션 수준 오류만 포착하고 싶을 뿐입니다. 예외로 인해 코드가 생성되었습니다.

다행히도 이를 쉽게 수행할 수 있는 방법이 있습니다.

StandardError를 대신 구출

주의해야 할 모든 예외는 StandardError에서 상속됩니다. . 이것은 우리의 오랜 친구입니다:

  • 메서드 오류 없음 - 존재하지 않는 메소드를 호출하려고 할 때 발생

  • 유형 오류 - 1 + ""와 같은 요인으로 인해 발생

  • 런타임 오류 - 누가 예전의 RuntimeError를 잊을 수 있겠습니까?

이와 같은 오류를 복구하려면 StandardError를 복구해야 합니다. . 다음과 같이 작성하면 됩니다.

begin
  do_something()
rescue StandardError => e
  # Only your app's exceptions are swallowed. Things like SyntaxErrror are left alone. 
end

하지만 Ruby 덕분에 사용이 훨씬 쉬워졌습니다.

예외 클래스를 전혀 지정하지 않으면 Ruby는 사용자가 StandardError를 의미한다고 가정합니다. 따라서 아래 코드는 위 코드와 동일합니다.

begin
  do_something()
rescue => e
  # This is the same as rescuing StandardError
end

사용자 정의 예외는 StandardError에서 상속되어야 함

사용자 정의 예외를 생성하는 경우 이것이 의미하는 바는 무엇입니까?

이는 항상 StandardError에서 상속해야 함을 의미합니다. , 그리고 Exception에서 절대 발생하지 않습니다. . Exception에서 상속하는 것은 예상되는 구조 동작을 깨뜨리기 때문에 좋지 않습니다. 사람들은 모든 애플리케이션 수준의 오류를 구하고 있다고 생각할 것이지만 귀하의 오류는 계속 진행됩니다.

class SomethingBad < StandardError
end

raise SomethingBad

예외 트리

Ruby의 예외는 클래스 계층 구조에서 구현되기 때문에 레이아웃을 확인하는 것이 도움이 될 수 있습니다. 다음은 Ruby의 표준 라이브러리와 함께 제공되는 예외 클래스 목록입니다. 레일과 같은 타사 보석은 이 차트에 추가 예외 클래스를 추가하지만 모두 이 목록의 일부 클래스에서 상속합니다.

Exception
 NoMemoryError
 ScriptError
   LoadError
   NotImplementedError
   SyntaxError
 SignalException
   Interrupt
 StandardError
   ArgumentError
   IOError
     EOFError
   IndexError
   LocalJumpError
   NameError
     NoMethodError
   RangeError
     FloatDomainError
   RegexpError
   RuntimeError
   SecurityError
   SystemCallError
   SystemStackError
   ThreadError
   TypeError
   ZeroDivisionError
 SystemExit
 fatal