Rubyの初級テクニック*1であるModule#module_evalですが、初級者には厳しい落とし穴がありました。
ただし、ローカル変数は module_eval/class_eval の外側のスコープと共有します。文字列が与えられ場合には、定数とクラス変数のスコープは自身のモジュール定義式内と同じスコープになります。ブロックが与えられた場合には、定数とクラス変数のスコープはブロックの外側のスコープになります。
502 Bad Gateway
ローカル変数は良いとして、定数とクラス変数はひどい。
文字列もブロックも一緒だろってことで、1行は文字列、複数行はブロックにしてたけど、ブロックだとたまに思った通りに動かない時があって、仕方なくヒアドキュメントで書いたりしていたのだけれど、これのせいですね。
class Foo; @@a = 1 end Foo.class_eval %[ p @@a ] #=> 1 Foo.class_eval { p @@a } #=> NameError
ややこしい。
*1:初級者ほど多用するという意味で