1

我们可以在语句之后放置一个类或模块rescue,但是在下面的代码中,我看到了一个方法rescue,它不适合这种模式。它是如何工作的,它是如何产生它所设计的输出的?

def errors_with_message(pattern)
  # Generate an anonymous "matcher module" with a custom threequals
  m = Module.new
  (class << m; self; end).instance_eval do
    define_method(:===) do |e|
      pattern === e.message
    end
  end
  m
end
puts "About to raise"
begin
  raise "Timeout while reading from socket"
rescue errors_with_message(/socket/)
  puts "Ignoring socket error"
end
puts "Continuing..."

输出

About to raise
Ignoring socket error
Continuing...
4

1 回答 1

4

救援需要一个类或一个模块,真的。因此,该方法创建了一个具有特殊行为的匿名模块。您会看到,当rescue搜索处理程序时,它将===运算符应用于您提供的异常类/模块,并将实际异常作为参数传递。

begin
  # do something
rescue MyCustomError
  # process your error
rescue StandardError
  # process standard error
end

因此,如果StandardError(或其后代之一)被提升,第一个处理程序将被跳过,第二个处理程序将被匹配。

现在,来自的模块errors_with_message很特别。它重新定义了 threequals 运算符以匹配异常消息。因此,如果引发错误并且其消息包含单词“socket”,则此处理程序将匹配。很酷的把戏,对吧?

于 2013-02-09T11:15:52.837 回答