C#erがRubyのModuleについてのinstance_evalとmodule_evalを理解するのにハマった点をまとめておく。
サンプルに使用するモジュールの定義
module M
CONST = "Module CONST"
class << self
CONST = "Module Singleton CONST"
end
end
文字列を使用してinstance_evalする場合
モジュールの特異メソッドが定義される
モジュールの特異クラス内で評価
M.instance_eval(<<-CODE)
def say
p CONST
end
CODE
M.say # => "Module Singleton CONST"
関数の定義はdef say
でもdef self.say
でも直接呼び出せる。
今の理解度では、def self.say
がOKな理由がわからない。
def self.say
は、特異クラスの特異クラスに定義されそうな気がするのだが。。。
文字列を使用してmodule_evalする場合
モジュールのインスタンスメソッドが定義される
モジュール内で評価
M.module_eval(<<-CODE)
def self.say
p CONST
end
CODE
M.say # => "Module CONST"
関数の定義はdef self.say
でなければ直接呼び出せない。
コードでinstance_evalする場合
モジュールの特異メソッドが定義される
カレント(この場合はトップレベル)で評価
CONST = 'TOP LEVEL'
M.instance_eval{
def say
p CONST
end
}
M.say # => "TOP LEVEL"
関数の定義はdef say
でもdef self.say
でも直接呼び出せる。
今の理解度では、def self.say
がOKな理由がわからない。
コードでmodule_evalする場合
モジュールのインスタンスメソッドが定義される
カレント(この場合はトップレベル)で評価
CONST = 'TOP LEVEL'
M.module_eval{
def self.say
p CONST
end
}
M.say # => "TOP LEVEL"
関数の定義はdef self.say
でなければ直接呼び出せない。
class << Module を使用する場合
モジュールの特異メソッドが定義される
モジュールの特異クラス内で評価
class << M
def say
p CONST
end
end
M.say # => "Module Singleton CONST"
関数の定義はdef say
でなければ直接呼び出せない。
文字列を使用してinstance_evalする場合と似ているが、def self.say
は直接呼び出せない。
深すぎるよ。。。