3

これが私のコードです:

module Star
  def Star.line
    puts '*' * 20
  end
end

module Dollar
  def Star.line
    puts '$' * 20
  end
end

module At
  def line
    puts '@' * 20
  end
end

include At
Dollar::line # => "@@@@@@@@@@@@@@@@@@@@"
Star::line   # => "$$$$$$$$$$$$$$$$$$$$"
Dollar::line # => "@@@@@@@@@@@@@@@@@@@@"
line         # => "@@@@@@@@@@@@@@@@@@@@"

この結果を得る方法を誰か説明できますか? ここでのメソッド ルックアップ フローがわかりません。

4

3 に答える 3

7

これは私がそれを見る方法です:

Dollar::line

このモジュールにはそのようなメソッドが定義されていないため、このモジュールをインクルードしたために呼び出しAt::lineています。

Star::line

Dollarモジュールからの最後の定義を使用します(元のStar定義の後になるため、オーバーライドされます)。

Dollar::line

3 回目の呼び出しは、最初の呼び出しと同じです。

line

そして最後はAt::lineあなたがインクルードしたからです。

于 2015-07-09T14:05:55.197 に答える
1

module Dollar
   def Star.line

意図的ですか、それともタイプミスですか?

Dollar.lineが定義されていないように見えますが、代わりにメソッドlineinAtが使用されています。

于 2015-07-09T14:15:52.413 に答える
1

まず、Ruby がメソッドと同じように定数を検索することを理解する必要があります。現在のレキシカルスコープで定数を探すことから始めます。そこに定数が見つからない場合は、1 レベル上に移動してそこを探します。定数がどこにも見つからない場合は、最終的に最上位を検索します。これがKernel、コードのどこからでもモジュールにアクセスできる理由です。

module Star
end
Star.object_id # 20

module Dollar
  Star.object_id # 20. No Star in current scope, so gets the top-level star
end

module At
  module Star
  end
  Star.object_id # 10. There is now a Star in this scope, so we don't get the top-level one
end

次に理解しておくべきことは、Ruby の最上位で定義されたメソッドは のインスタンスメソッドになるということですObject。Ruby ではすべてが のインスタンスであるObjectため、そのようなメソッドはいつでも呼び出すことができます。

最後に、includeモジュールからインスタンス メソッドを取得し、それらを現在のスコープ内のインスタンス メソッドにします。したがってinclude、トップレベルで何かを行うと、これらすべてのメソッドがObject!に追加されます。

したがって、コードは本質的にこれと同等です。

module Star
  def self.line
    puts '*' * 20
  end

  # this overwrites the previous definition
  def self.line
    puts '$' * 20
  end
end

# because of the way constants are looked up, the def ends up in Star
module Dollar
end

module At
  def line
    puts '@' * 20
  end
end

# the include does this, so now every object (including Dollar) can call line
def line
  puts '@' * 20
end

# except Star already has its own line method, so the one from Object won't be called for it
Star.line # "$$$$$$$$$$$$$$$$$$$$"
于 2015-07-09T17:34:49.900 に答える