ruby 异常处理:rescue

一个运行着的程序常会遇到意外的问题.一个要读取的文件不存在;当希望存入一些数据时磁盘满了;用户可能输入不恰当的数据.

ruby> file = open("some_file")
ERR: (eval):1:in `open': No such file or directory - some_file

一个健壮的程序会合理并漂亮的处理这些问题.面对那些异常是一件讨人厌的工作.C程序员被要求做到检查每一个可能导致错误发生的系统调用的返回值并立刻做出决定.

FILE *file = fopen("some_file", "r");
if (file == NULL) {  
fprintf( stderr, "File doesn't exist.\n" );  
exit(1);
}
bytes_read = fread( buf, 1, bytes_desired, file );
if (bytes_read != bytes_desired ) {  
/* do more error handling here ... */
}
...

这项无聊的工作会使程序员最终变得马虎并忽略掉它,结果是程序无法应对异常.令一方面,这样也会降低程序的可读性.因为过多的错误处理使有意义的代码也变得杂乱了.

在Ruby里,就像其它的现代语言,我们可以通过隔离的办法处理代码域里的异常,因此,这有着惊人的效果却又不会为程序员或以后希望读它的其它人造成过度的负担.代码域由begin开始直到遇到一个异常,这将导致转向一个由rescue标记的错误处理代码域.如果异常没发生,rescue代码就不会使用.下面的代码返回文本文件的第一行,如果有异常则返回 nil.

def first_line( filename )
  begin
    file = open("some_file")
    info = file.gets
    file.close
    info  # Last thing evaluated is the return value
  rescue
    nil   # Can't read the file? then don't return a string
  end
end

有时我们会希望围绕问题展开创造性工作.这里,如果文件不存在,我们用标准输入代替:

begin
  file = open("some_file")
rescue
  file = STDIN
end
begin
  # ... process the input ...
rescue
  # ... and deal with any other exceptions here.
end

retry 用于 rescue 代码表示又重新执行 begin 代码.这让我们可以压缩前面的例子:

fname = "some_file"
begin
  file = open(fname)
  # ... process the input ...
rescue
  fname = "STDIN"
  retry
end

但这仍有一点瑕疵.一个不存在的文件将导致不停止地 retry.你在使用 retry 做异常处理时应注意到这一点.

每个Ruby库在遇到错误时都会提交一个异常,你可以在自己的代码里明确地提交异常.用 raise 来提交异常.它带一个参数,也就是描述异常的一个字符串.参数是可选的但不应被省略.之后它可以通过一个特殊的全局变量 $! 访问.

ruby> raise "test error"
   test error
ruby> begin
    |   raise "test2"
    | rescue
    |   print "An error occurred: ",$!, "\n"
    | end
An error occurred: test2
   nil

(0)

相关推荐

  • Ruby中的异常处理代码编写示例

    单个异常使用 fail 关键字仅仅当捕获一个异常并且反复抛出这个异常(因为这里你不是失败,而是准确的并且故意抛出一个异常). begin fail 'Oops' rescue => error raise if error.message != 'Oops' end 不要为 fail/raise 指定准确的 RuntimeError. # bad fail RuntimeError, 'message' # good - signals a RuntimeError by default fai

  • 详解Ruby中的异常

    异常和执行总是被联系在一起.如果您打开一个不存在的文件,且没有恰当地处理这种情况,那么您的程序则被认为是低质量的. 如果异常发生,则程序停止.异常用于处理各种类型的错误,这些错误可能在程序执行期间发生,所以要采取适当的行动,而不至于让程序完全停止. Ruby 提供了一个完美的处理异常的机制.我们可以在 begin/end 块中附上可能抛出异常的代码,并使用 rescue 子句告诉 Ruby 完美要处理的异常类型. 语法 begin # - rescue OneTypeOfException #

  • ruby 异常处理:ensure

    当一个方法结束工作时我们也许需要进行清理工作.也许一个打开的文件需要关闭,缓冲区的数据应清空等等.如果对于每一个方法这里永远只有一个退出点,我们可以心安理得地将我们的清理代码放在一个地方并知道它会被执行;但一个方法可能从多个地方返回,或者因为异常我们的清理代码被意外跳过. begin   file = open("/tmp/some_file", "w")   # ... write to the file ...   file.close end 上面,如果在我们

  • ruby 异常处理:rescue

    一个运行着的程序常会遇到意外的问题.一个要读取的文件不存在;当希望存入一些数据时磁盘满了;用户可能输入不恰当的数据. ruby> file = open("some_file") ERR: (eval):1:in `open': No such file or directory - some_file 一个健壮的程序会合理并漂亮的处理这些问题.面对那些异常是一件讨人厌的工作.C程序员被要求做到检查每一个可能导致错误发生的系统调用的返回值并立刻做出决定. FILE *file =

  • Terry七月Ruby读书笔记(比较详细)第1/4页

    Page 3 概述 ¨         解释执行:Python,Ruby,交互性很好: ¨         编译执行:Pascal, C,速度较快. n         本地执行,如C,C++: n         虚拟机执行,如Java, C#. ¨         动态语言,如JavaScript,Ruby: ¨         静态语言,如C++,Java. 语言 ¨         语法 关键字 ¨         语义 ¨         语用 松本行弘(Matz) 1993 Ruby

  • Ruby和Ruby on Rails中解析JSON格式数据的实例教程

    Ruby解析JSON Ruby解析Json例子: json = '["a", "B", "C"]' puts "Unsafe #{unsafe_json (json).inspect}" #输出Unsafe ["a", "B", "C"] Ruby解析Json把上面的json字符串解析成Array.这样的方法并不安全,比如: json = 'puts "Da

  • 用实际代码演示Ruby的容易被误解的6个特性

    简介: 假设您是一名 C++ 开发人员,您需要使用 Ruby 快速执行一些原型设计.当您拿起一本 Ruby 参考书籍(比如 Pickaxe)或浏览 Ruby 网站时,会看到一些熟悉的构造,比如类声明.线程支持和异常处理.正当您认为自己了解 Ruby 的工作原理之时,您意识到了,您 Ruby 代码中的并发机制与 Boost 线程工作原理不一样,catch 和 throw 也与它们看上去的大不相同,而且其他人在其 Ruby 脚本中各处使用了名为 self 的关键词.欢迎来到 Ruby 的世界中! 如

  • 初步了解一下什么是ruby

    关键字 def undef 方法定义 module 模块定义 class 类定义 defined? 检查类型 条件语句 if,then,else,elsif,case,when,unless 循环语句 for ,in,while,until,next,break,do,redo,retry,yield 逻辑判断 not ,and ,or 逻辑或空值 true,false,nil 异常处理 rescue,ensure 对像引用super ,self 嵌入模块BEGIN END 块的起始 begin

  • Ruby 中的 module_function 和 extend self异同

    在阅读开源的 Ruby 代码和编写可维护性的代码经常遇到这两者的使用,那么他们两者的共同点和区别是什么呢? module_function Ruby 的 module 是 method 和 constants 的集合.module 中的method 又可分为 instance method 和 module method, 当一个 module 被 include 进一个 class ,那么 module 中的 method (注:没有被 module_function 标记的 method)就

  • ruby ftp封装实例详解

     ruby ftp封装实例详解 最近自己用ruby 封装了一个Net::FTP的工具类. class FtpTool def initialize() @current_ftp = create_ftp end # 获取指定格式的文件名称列表 # 例如: source = "test/*.txt" # 返回: [source/file_name.txt] def fetch_remote_filenames(source) return [] if source.blank? log_

随机推荐