どうもこんにちは。
今回も完全なるメモ書きです。温かい目で見守ってください。
定数の探索
module M
CONST = "Hello, world"
class C
def awesome_method
CONST # レキシカルスコープ内で`CONST`が定義されているので、参照ができる
end
end
end
p M::C.new.awesome_method
module M
CONST = "Hello, world"
end
class M::C
# ここに`CONST`が定義されていれば参照可能
def awesome_method
CONST # レキシカルスコープ内に`CONST`が定義されていないので、参照ができない
end
end
p M::C.new.awesome_method
定数の探索は基本的にレキシカルスコープで行われますが、レキシカルスコープ内に定数が見つからなかった場合には、継承元クラスへ定数の探索を行います。
さぁ、ここからclass_eval
出てきます!
class C
end
module M
CONST = "Hello, world"
C.class_eval do # `class_eval`にはブロックが渡されています。この時のブロック内のネストの状態はモジュールMになります。
def awesome_method
CONST # ネストの状態はモジュールMであり、レキシカルスコープ内にCONSTも存在しているので、参照が可能
end
end
end
p C.new.awesome_method
class C
CONST = "Hello, world"
end
module M
C.class_eval(<<-CODE) # `class_eval`にはヒアドキュメントが渡されています。この時のネストの状態はクラスCです。
def awesome_method
CONST # ネストの状態がクラスCである、クラスCに`CONST`が定義されているので、CONSTの参照が可能
end
CODE
end
p C.new.awesome_method
class C
CONST = "Hello, world"
end
module M
C.class_eval do # `class_eval`にはブロックが渡されています。この時のブロック内のネストの状態はモジュールMになります。
def awesome_method
CONST # ネストの状態はモジュールMですが、レキシカルスコープ内に`CONST`が存在していないので参照が不可能
end
end
end
p C.new.awesome_method