shimgo
4/3/2016 - 5:13 AM

module の使用方法について

module の使用方法について

require 'pp'

module Initializable
  def initialize(content)
    p 'Module initialized'
    @content = 'Module content'
  end
  # モジュールメソッドはinclude、extendしたクラスから
  # [モジュール名].[メソッド名]で呼び出し可能
  def self.module_method
    p 'Module method'
  end
  def mod_public_method
    p 'Module public method'
  end
  # モジュール関数
  # 「privateなインスタンスメソッドであると同時に
  # モジュールの特異メソッドでもある」メソッド
  def my_module_function
    p 'Module function'
  end
  module_function :my_module_function
end

class PostIncluded
  # モジュールをインスタンスメソッドとして取り込み
  include Initializable
  attr_reader :content
  def initialize(content)
    p 'Post initialized'
    @content = content
    # superでincludeしたmoduleを呼び出し可能
    super
    Initializable.module_method
  end

  def module_function_test
    # モジュール関数は2つの方法でよびだせる
    Initializable.my_module_function # レシーバにモジュールを指定して呼び出し
    my_module_function # includeしてそのまま呼び出し
  end
end

class PostExtended
  # モジュールをクラスメソッドとして取り込み
  extend Initializable
  attr_reader :content
  def initialize(content)
    p 'Post initialized'
    @content = content
    # extendしたのでsuperで呼び出すのは親クラスのinitialize
    # super => ArgumetnError
    # extendしてもモジュールメソッドは呼び出し可能
    Initializable.module_method
  end

end

p '==included=='
a = PostIncluded.new('Post content')
p a.content
a.module_function_test
#a.my_module_function # => NoMethodError モジュール関数はprivateメソッドなので呼び出せない
p '==included=='
p ''
p '==extended=='
b = PostExtended.new('Post content')
# extendしたモジュールメソッドはクラスメソッドとして
# よびだせるけどinitializeは無理っぽい
PostExtended.mod_public_method
# PostExtended.initialize('Post content') => NoMethodError

p '==extended=='