9

How is it that Ruby allows a class access methods outside of the class implicitly?

Example:

class Candy
    def land
        homer
    end
end

def homer
    puts "Hello"
end

Candy.new.land #Outputs Hello
4

4 に答える 4

24

The definition of the "homer" method is adding the method to the Object class. It is not defining a free function.

Class Candy implicitly inherits from Object, and so has access to the methods in Object. When you call "homer" in the "land" method, the method resolution can't find a definition in the current class, goes to the super class, finds the method you have added to Object, and calls it.

于 2008-10-01T06:08:02.923 に答える
5

何が起こるかを知る簡単な方法

  1. Candy オブジェクトで使用されるメソッドを解決するために、どのクラス/モジュールが検索されますか?

    p Candy.ancestors #=> [キャンディー、オブジェクト、カーネル]

  2. Candy にはホーマーというメソッドがありますか?

    p Candy.instance_methods(false).grep("homer") #=> []

    p Candy.private_instance_methods(false).grep("homer") #=> []

  3. OK Candy には「ホーマー」と呼ばれるメソッドはありません。

  4. ルックアップ チェーンの次 (1 を参照) => 「オブジェクト」

  5. オブジェクトには「ホーマー」というメソッドがありますか? p Object.instance_methods(false).grep("homer") #=> []

    p Object.private_instance_methods(false).grep("homer") #=> ["homer"]

Candy のルックアップ チェーンには Object があり、これにはプライベート インスタンス メソッド「homer」があるため、メソッド解決は成功します。

def ステートメントは常に、定義の時点での自己のクラスでメソッドを定義します

  1. homer が定義される直前のselfとは?

    p self #=> main def homer puts "Hello" end

  2. それで、そのタイプは何ですか?

    p self.class #=> オブジェクト

これが、ホーマーオブジェクトに行き着く理由です

于 2008-10-02T22:16:49.513 に答える
4

技術的には、メソッドの定義は、直接ではなく、homer実際には にKernel混在するモジュールにあります。したがって、が で定義されたローカル変数またはインスタンス メソッドではない場合、Ruby メソッドの継承チェーンは、mix-inモジュールまでたどられてから、このコードが実行されます。ObjectObjecthomerCandyObjectKernel

編集:申し訳ありませんが、なぜこれを考えたのかわかりません。この方法は実際に生き続けているようObjectです。実際にはそれほど大きな違いがあるかどうかはわかりませんが、投稿する前に確認する必要がありました。

于 2008-10-02T06:38:59.877 に答える
0

Ruby にはフリー フローティング関数がありません。すべてのメソッドは、何らかのオブジェクトに属しています。def最上位のメソッドは、実際には class のインスタンス メソッドになっていますObject。すべてはあるObjectレベルで であるため、すべてのオブジェクトはObjectのインスタンス メソッドにアクセスできます。

于 2011-11-27T15:45:16.773 に答える