Rubyのmodule_functionは、引数なしで指定できる

Classにmoduleをmix-inしてもmoduleで定義したクラスメソッドを利用できない。

これを解決するために、以下ようにincludeされた時点でクラスに対してmoduleをextendする方法がある。

module M
  def self.included(klass)
    klass.extend ClassMethods
  end

  module ClassMethods
    def expand_class_method_to_included
      puts "expand_class_method_to_included"
    end
  end
end

class MyM
  include M
end

module_functionでも、問題を解決することができる。

Rubyドキュメントのコード例から、以下のようにmodule_function引数を都度指定する必要があると勘違いしていた。

module MyModule
  def hello
    'hello'
  end

  module_function :hello
end

module_functionの説明を詳しく確認すると、引数なしのときは今後このモジュール定義文内で新しく定義されるメソッドをすべてモジュール関数にします。の一文がある。

このことから、以下のようにmodule_functionを利用するとそれ以降のメソッドがモジュール関数になることがわかる。

module MyModule
  module_function
  def hello
    'hello'
  end

  def hi
    'hi'
  end
end

puts MyModule.hello
puts MyModule.hi

下記の場合、モジュール関数になるのはhiメソッドのみである。

module MyModule
  def hello
    'hello'
  end

  module_function

  def hi
    'hi'
  end
end

puts MyModule.hello
puts MyModule.hi

改訂2版 パーフェクトRuby

改訂2版 パーフェクトRuby

  • 作者:Rubyサポーターズ
  • 出版社/メーカー: 技術評論社
  • 発売日: 2017/05/17
  • メディア: 大型本