module_function
と extend self
の違いやモジュール関数についてよくわからなかったので調べた結果をまとめる。
module_function
は、特異メソッドとプライベートメソッドを同時に定義するためのメソッドです。
特異メソッドであり、プライベートメソッドでもあるメソッドのことを「モジュール関数」と呼びます。
module M
module_function
def hoge
'hoge'
end
end
モジュール関数は (パブリックな) 特異メソッドであるので、モジュールをレシーバに指定して呼び出すことができます。
M.hoge # => 'hoge'
また、プライベートメソッドでもあるので include
することでレシーバを省略して呼び出せるようになります。
class C
include M
def fuga
hoge
end
end
C.new.fuga # => 'hoge'
include
してもそのクラスにパブリックメソッドが追加されるわけではありません。
C.new.hoge # => NoMethodError: private method `hoge' called
extend self
は自身の持つメソッド全てを自身の特異メソッドとして定義します。
この場合、特異メソッドと定義したメソッドのスコープは同じになります。
つまり、パブリックメソッドとして定義するとモジュールを指定して呼べますが include
した際にパブリックメソッドとして追加されるようになり、プライベートメソッドとして定義するとモジュールを指定して呼べず、 include
した際にプライベートメソッドとして追加されます。