我们可以在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...
答案 0 :(得分:4)
Rescue需要一个类或一个模块,为true。因此,该方法创建具有特殊行为的匿名模块。您会看到,当rescue
搜索处理程序时,它会将===
运算符应用于您提供的异常类/模块,并将实际异常作为参数传递。
begin
# do something
rescue MyCustomError
# process your error
rescue StandardError
# process standard error
end
因此,如果引发StandardError
(或其后代之一),将跳过第一个处理程序并匹配第二个处理程序。
现在,来自errors_with_message
的模块很特别。它重新定义了三元运算符以匹配异常消息。因此,如果引发错误并且其消息包含单词“socket”,则此处理程序将匹配。很酷的伎俩,嗯?