Module#class_evalの引数
Module#class_evalには、引数に文字列またはブロックを受け取ります。
class_eval(expr, fname = "(eval)", lineno = 1) -> object
class_eval {|mod| ... } -> object
引数が文字列の時とブロックの時では、スコープが異なります。
文字列が与えられた場合には、定数とクラス変数のスコープは自身のモジュール定義式内と同じスコープになります。
ブロックが与えられた場合には、定数とクラス変数のスコープはブロックの外側のスコープになります。
引数が文字列とブロックでは、スコープはどのように違うのでしょうか。
動作の違いを確認しました。
引数が文字列の時のスコープ
文字列が与えられた場合には、定数とクラス変数のスコープは自身のモジュール定義式内と同じスコープになります。
引数が文字列の場合は、クラスCの定数XXXにアクセスできるため、次のコードは動作しました。
class C
XXX = 'XXX'
end
C.class_eval(<<-CODE)
def foo
XXX
end
CODE
p C.new.foo
引数がブロックの時のスコープ
引数がブロックの場合は、クラスCの定数XXXにアクセスできないため、次のコードはエラーになりました。
class C
XXX = 'XXX'
end
C.class_eval do
def foo
XXX
end
end
p C.new.foo