2011-02-22 9 views
0

Rubyインタプリタは、定義がまだ解釈されていなければ、オブジェクトにメソッドが存在することをどのように知っていますか?同様に、最初にメソッドを定義するかどうかは、それを使用するのではなく、定義してから定義するかどうかは関係ありませんか?Rubyはメソッドが存在することをいつ知っていますか?

答えて

5

実行するまでは分かりませんが気にしません。メソッド呼び出し文が実行されると、インタプリタはクラス(オブジェクトではなくコード!)が名前付き関数を持っているかどうかを調べます。そうでなければ、それは祖先の木を探します。見つからない場合はmethod_missingメソッドを呼び出します。それが定義されていない場合は、エラーが発生します。

関数呼び出しが実行されない場合、エラーは発生しません。

1

問題は、インタプリタが使用するときにそれを見つけようとしましたが、そこには存在しないため、失敗する可能性があります。

コンパイルされた言語では、コンパイル時に「これを2番目のパスで検索します」と言われるかもしれませんが、Rubyの場合はそうは思わないでしょう。

+2

これは本当ではありません。コンパイルされた言語(例えばC言語)があり、これはシングルパスであり、使用する前に各関数を宣言する必要があります。また、解釈された言語が複数のパスを使用できず、関数やメソッドを定義する前にそれを使用できる理由はありません。 Rubyがこれをしない理由は、実行時にルビメソッドの定義が行われ、メソッドが実際に複数回またはループ内で定義できるため、メソッド定義が最初のパスで相互作用するときにそれらを単一にすることはできません他のコードと一緒に。 – sepp2k

+0

あなたが正しいです、私は答えを修正します。 – OscarRyz

3

インタプリタは、例えば、事前に未定義の方法を知っていません:

o = Object.new 
o.foo # => Raises NoMethodError. 
class Object 
    def foo 
    puts "Foo!" 
    end 
end 
o.foo # => prints "Foo!", since the method is defined. 

をしかし、Rubyはメソッド呼び出しの受信機は、メソッド名と引数を取りましょうmethod_missingと呼ばれる巧妙な機能を持っています定義されたメソッドがすでに呼び出しを処理していない限り、それに応じて処理します。

def o.method_missing(sym, *args) 
    puts "OK: #{sym}(#{args.inspect})" 
    # Do something depending on the value of 'sym' and args... 
end 
o.bar(1, 2, 3) #=> OK: bar(1, 2, 3) 

「メソッドが見つかりません」は、アクティブなレコード検索メソッドなど、「動的に定義された」機能を持つ意味がある場所で使用されます。

関連する問題