Rescue语句在连续过滤不同错误时效果很好:
o = Object.new
begin
o.foo
rescue ArgumentError
puts "Object o does define #foo, but you got the argument number wrong!"
rescue NoMethodError
puts "Object o does not respond to #foo!"
else
puts "That's right!"
end
但是当涉及用不同的参数挽救相同的错误时,这就是我在我的代码中使用的内容:
o = Object.new
begin
o.foo
rescue NoMethodError
begin
o.bar
rescue NoMethodError
begin
o.quux
rescue NoMethodError
warn "Object o responds not to basic methods!"
end
end
end
毋庸置疑,我不喜欢它。难道没有更聪明的方法吗?
答案 0 :(得分:2)
可能这不回答你的问题,但在这种情况下,我会在调用之前询问o
是否responds_to?
我要调用的方法:
method = [:foo, :bar, :baz].find { |m| o.respond_to?(m) }
if method
o.public_send(method)
else
warn "Object o responds not to basic methods!"
end
答案 1 :(得分:1)
def send_messages_maybe(object, messages, *parameters)
object.send(messages.first, *parameters)
rescue NoMethodError
messages = messages[1..-1]
if messages.empty?
warn "Object does not respond to basic methods!"
else
retry
end
end
module Quux
def quux(*args)
puts "quux method called with #{args.inspect}"
end
end
messages = %i{foo bar quux}
send_messages_maybe(Object.new, messages)
send_messages_maybe(Object.new.extend(Quux), messages, 10, :hello, 'world')
输出:
Object does not respond to basic methods!
quux method called with [10, :hello, "world"]
这适用于没有定义#respond_to_missing?
方法的对象,这很常见 - 我见过的大多数使用#method_missing
的代码属于此类别。