class_eval (module_eval)でのクラス変数とクラス定数

クラス定義の外側で、class_evalのブロックを使ってクラス変数とクラス定数にアクセスしようとすると、Ruby 1.8ではNameErrorが発生します。class_execでも同様です。コードをブロックではなく文字列で渡したときはアクセスできます。

Ruby 1.9.1ではブロック内でもクラス変数・定数にアクセスできるように修正されましたが、1.9.2では1.8と同じ動作に戻されました。

class Foo
  @@var = 123
  VAR = 456
end

Foo.class_eval <<-EOS
  p @@var #=> 123
  p VAR   #=> 456
EOS

Foo.class_eval do
  p @@var #=> NameError(1.8/1.9.2) / 123(1.9.1)
  p VAR   #=> NameError(1.8/1.9.2) / 456(1.9.1)
end

「1.9.2では仕様が1.8に戻る」というのはけっこうありそうな感じです。Rubyリファレンスでは、ここらへんの細かいことは各メソッドのページには載せないで、「細かいこと」専用ページを別に作ろうかと考え中。

参考: