15


5

Rubyモジュールと自己拡張

コードはどのような状況にあります:

module M
   extend self
   def greet
    puts "hello"
   end

end

次のような言い方をすると、より有益です。

module M
   def self.greet
    puts "hello"
   end
end

最上部では、1つは拡張されているインスタンスメソッドであり、後者は単なるクラスメソッドですが、いずれかのメソッドを呼び出す場合は、M.greetを使用する必要がありますか? 誰かが一方のコードをもう一方のコードよりも使用するタイミングに光を当てることができるかどうかに興味がありました。 ありがとうございます。

3 Answer


15


最初の例は通常、人々が `module_function`の機能を実現する方法です(このメソッドの存在を知らない場合)。

`module_function`はインスタンスメソッドとクラスメソッドの両方です。 2番目のコード例では、メソッドは単なるクラスメソッドです。


10


最初の例ではこれを行うことができますが、2番目の例ではできません。

include M
greet


4


モジュールは、モジュールメソッドを記述することでネームスペースとして使用でき、モジュールのインスタンスメソッドを別のオブジェクトに混在させることができます。

_self-extending_モジュールの概念により、モジュールを両方の方法で使用できます。スタンドアロンの名前空間として、またはミックスインとして。 このモジュールを検討してください:

module M
  def bar
    puts "bar"
  end
end
class C
  include M
end

インスタンスメソッドがあり、別のオブジェクトに混在させることができます。 モジュールメソッドがないため、名前空間として使用できません。

puts M::bar # => undefined method `bar' for M:Module
puts C.bar  # => this is bar

しかし、私たちが実証できるように、モジュールはクラス `Module`の単なるオブジェクトです

puts M.class   # => Module

これは、私たちが何かおかしなことができることを意味します。 モジュールを自分自身に混ぜて、そのメソッドがインスタンスとモジュールの両方のメソッドになるようにすることができます。

module M
  extend self
  def bar
    puts "bar"
  end
end
puts M::bar # => this is bar
puts C.bar  # => this is bar