2

method_missing

*obj.method_missing( シンボル h ,引数 i ) → other_obj

obj が処理できないメッセージを送信されたときに、Ruby によって呼び出されます。symbol は呼び出されたメソッドのシンボルで、args はそれに渡された任意の引数です。以下の例では、ローマ数字で構成される名前のメソッドに応答し、対応する整数値を返すクラス Roman を作成します。method_missing のより一般的な用途は、プロキシ、委任者、およびフォワーダーを実装することです。

class Roman
  def roman_to_int(str)
    # ...
  end
  def method_missing(method_id)
    str = method_id.id2name
    roman_to_int(str)
  end
end
r = Roman.new
r.iv ! 4
r.xxiii ! 23
r.mm ! 2000

メソッドの欠落について聞いたばかりで、Ruby のプログラミングで詳細を調べに行きましたが、本から引用した上記の説明は頭に浮かびません。誰でも簡単に説明できますか?より具体的には、メソッド欠落はインタープリターによってのみ使用されますか、それともプログラムで直接呼び出す必要がありますか (NASA のコードを書くのではなく、Web アプリを書いているだけだと仮定します)?

4

7 に答える 7

12

ruby がメソッドを持っているとは考えないほうがよいでしょう。ruby の「メソッド」を呼び出すと、実際にはそのインスタンス (またはクラス) にメッセージが送信されます。メッセージのハンドラーを定義している場合は、それを使用して処理し、値を返します。

rubymethod_missingが適切なハンドラーを見つけられないときに呼び出される特別な定義も同様です。メソッドのようなものと考えることもできます*

于 2009-04-03T20:29:51.117 に答える
5

Rubyにはタイプエンフォースメントがなく、同様に、スクリプトが最初に解析されるときにオブジェクトがどのメソッドを持っているかについてのチェックも行いません。これは、アプリケーションの実行時に動的に変更できるためです。

method_missingが行うことは、特定のオブジェクトには存在しないメソッドへの呼び出しをインターセプトして処理できるようにすることです。これは、Rubyで書かれたほとんどすべてのDSL(ドメイン固有言語)の背後にある内部の力を提供します。

この例の場合、「r.iv」、「r.mm」などのすべてが、実際にはRomanオブジェクトへのメソッド呼び出しです。もちろん、「iv」または「mm」メソッドがないため、代わりに制御がmethod_missingに渡されます。このメソッドは、呼び出されたメソッドの名前と、渡された引数を取得します。

次に、method_missingは、メソッド名をシンボルから文字列に変換し、それをローマ数字として解析して、出力を整数として返します。

于 2009-04-03T21:18:12.313 に答える
5

これは基本的に、どのメソッドにも一致しないメッセージのキャッチオールです。動的ファインダーのアクティブ・レコードで広く使用されています。それはあなたがこのようなものを書くことを可能にするものです:

SomeModel.find_by_name_and_number(a_name, a_number)

モデルにはそのfind_byのコードが含まれていないため、method_missingが呼び出され、それを見て、「私はその形式を認識し、それを実行します」と言います。そうでない場合は、メソッドが見つからないというエラーが発生します。

于 2009-04-03T20:07:28.147 に答える
3

あなたが提供するローマの例では、メソッドを明示的に定義せずにクラスの機能を拡張する方法を示しています。

r.iv はメソッドではないため、method_missingキャッチroman_to_intしてメソッド ID "iv"を呼び出します。

ドキュメントに記載されているように、プロキシ、デリゲーター、フォワーダーなど、認識されていないメソッドを他の場所で処理する場合にも役立ちます。

于 2009-04-03T20:18:04.017 に答える
1

Web アプリケーションについて言及されているので、Ruby on Rails に精通していると思います。の使用方法の良い例method_missingは、利用可能なさまざまfind_by_<whatever>な方法です。これらのメソッドは実際には存在しません。これらは実行時に合成されます。この魔法はすべて、存在しないメソッドの呼び出しを ruby​​ がインターセプトする方法によって発生します。

それと method_missing のその他の使用法について詳しくは、こちらをご覧ください。

于 2009-04-03T21:30:23.140 に答える
1

ActiveRecord はmethod_missingfind_by メソッドを定義するために使用します。ただし、method_missingこれは基本的に最後の手段であるため、これは深刻なパフォーマンスのボトルネックになる可能性があります。私が発見したのは、ActiveRecord が新しいファインダー メソッドをクラス メソッドとして定義することにより、さらに素晴らしいメタプログラミングを行っていることです !! したがって、同じファインダ メソッドをさらに呼び出しても、method_missingそれはクラス メソッドになっているため、ヒットしません。base.rb の実際のコード スニペットの詳細については、ここをクリックしてください

于 2011-08-16T05:17:26.893 に答える