📜  红宝石 |例外

📅  最后修改于: 2022-05-13 01:55:34.068000             🧑  作者: Mango

红宝石 |例外

一个好的程序(或程序员)可以预测错误并安排以有效的方式处理它们。这并不像听起来那么容易。异常是在运行时发生的错误。它停止程序的执行。它们是由各种各样的异常情况引起的,例如内存不足、无法打开文件、试图将对象初始化为不可能的值等。

什么是例外?

异常是在程序执行期间(即在运行时)发生的不希望的或意外事件,它破坏了程序指令的正常流程。

错误与异常

错误:

  • 错误是计算机程序执行过程中可能出现的意外问题。
  • 无法处理错误。
  • 所有错误都是例外。

例外:

  • 异常是运行时可能出现的意外事件。
  • 可以使用 try-catch 机制处理异常。
  • 所有异常都不是错误。
处理异常的传统方法

处理异常的传统方法包括使用返回码。 open 方法返回一些特定的值并说它失败了。然后这个值被传回调用例程的层,直到有人想要对它负责。这种方法的问题是管理所有这些错误非常复杂。如果一个方法调用 open、read 并最后调用 close,那么每个方法都有可能返回错误指示。现在,函数将如何区分返回给调用者的值中的这些错误代码。

这里的异常类为这个问题提供了解决方案。异常类向程序或程序员提供有关将错误放入对象的封装信息。异常对象发送回调用堆栈,直到系统找到知道如何处理发生的错误的合适代码。

异常类及其层次结构

它是包含对象中异常信息的包。 Ruby 包含一个预定义的异常层次结构,如下所示:

在上图中,大多数异常都属于StandardError 类,这是 Ruby 程序中出现的一般异常。其余的异常描述了更严重、更低级别和更难恢复的情况,Ruby 程序不会尝试处理它们。当用户想要创建异常时,他可以使用内置异常类之一。在 Ruby 中,用户也可以创建自己的异常,但为此,他必须将该异常设为StandardError的子类或其子类之一。如果他没有在StandardError中定义,则默认情况下不会捕获异常。每个异常都包含消息字符串和堆栈回溯。因此,如果用户定义了自己的异常,那么他必须在其中添加此信息。

例子:

# Ruby program to illustrate the exception
   
# taking two integer value
$A = 14;
$B = 0;
  
# divide by zero error
$C = $A / $B;
  
puts "The Result is: #{$C}"

运行时错误:

解释:在上面的程序中,用户试图将 14 除以 0。所以这里 Ruby 编译器会抛出一个异常ZeroDivisionError

创建用户定义的异常: Ruby 使用称为raise内核方法来创建异常,这些异常将是 Exception 类或其子类之一的实例。 rescue子句用于处理 raise 创建的异常。

例子:

# Ruby program to create the user defined exception
  
# defining a method
def raise_exception
      
    puts 'This is Before Exception Arise!'     
      
    # using raise to create exception  
    raise 'Exception Created'     
      
    puts 'This is After Exception Arise -- Not Displayed'     
end     
  
# Calling the method
raise_exception

输出:

This is Before Exception Arise!
source_file.rb:9:in `raise_exception': Exception Created (RuntimeError)
    from source_file.rb:15:in `'

上述示例代码的解决方案:

# Ruby program to create the user 
# defined exception and rescued 
  
# defining a method
def raise_and_rescue     
  begin 
        
    puts 'This is Before Exception Arise!'
        
    # using raise to create an exception  
    raise 'Exception Created!'
  
    puts 'After Exception'  
  
  # using Rescue method
  rescue     
    puts 'Finally Saved!'     
    
end     
  
puts 'Outside from Begin Block!'     
  
end     
  
# calling method
raise_and_rescue    

输出:

This is Before Exception Arise!
Finally Saved!
Outside from Begin Block!

解释:在上面的例子中,异常是由 raise 方法引发的(raise 方法直接来自内核模块),代码由于异常的存在而被中断。现在,这个异常由rescue 子句处理,并且程序流在rescue 子句之后继续没有错误。如果程序包含多个救援子句,那么如果第一个救援代码无法处理异常,则下一个救援子句将处理异常。