eval族の親戚exec族

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)


メタプログラミングにもある程度ページ割いていて良いです。
7章 (7-3-5 module_exec / class_exec / instance_exec)より

block引数渡せて便利そうです。こんなんあったっけ。
(instance_exec のみでもいいのではという気もしますが、きっとそれぞれ存在する意味があるんでしょうな。特に調べてないけど。)
なぜか自分の環境ではinstance_evalが意図した動きにならない。

class EvalTarget
  CONST_VAL = "EvalTarget::CONST"
  attr_accessor :instance_val
end

CONST_VAL = "CONST"

e1 = EvalTarget.new

# evalのブロック内でCONST_VALを参照してもEvalTarget::CONST_VALが参照されてしまう
e1.instance_eval { @instance_val = CONST_VAL }
e1.instance_val # => "EvalTarget::CONST"
=> "CONST"  # なぜかCONSTになっちゃう。

本来ならEvalTarget::CONSTが参照されて、instance_exec 使うと幸せになりますよー って話。
便利そう。

# CONST_VALをinstance_execの引数で渡すと、このコンテキストのCONST_VALを渡せる
e1.instance_exec(CONST_VAL) { |const_val| @instance_val = const_val }
e1.instance_val
=> "CONST"