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=='