1

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

言うまでもなく、私はそれが好きではありません。これを行うためのより賢い方法はありませんか?

4

2 に答える 2

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
于 2013-06-13T18:50:46.620 に答える
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このカテゴリに分類されます。

于 2013-06-13T20:03:15.597 に答える