(define -ayalog '())

括弧に魅せられて道を外した名前のないプログラマ

Ruby の定数は奇妙だ

仕事で今まで奇跡的に動いていたコードが突然動かなくなるバグに遭遇して調べていたら、 Ruby の定数に関する仕様のせいだということが判明した。

class Hoge
  X = 'X'
end

という風に定義されている定数があるのを

class Fuga
  puts X # 本来なら動かない
end

という具合にいきなり呼び出して今まで動いていたコードがあった。
これは普通は動かないが次のようなコードが存在する場合動作するようになる。

Hoge.class_eval do
  X = 'X' # トップレベルへの宣言と同義
end

なんでこんなことをわざわざしてしまっているのか、というのは今のプロダクトに諸々の事情があり何故か存在するということ以外僕は知らない。
これは実際書いた人の心の中では、一番最初のコードと同じ意味なんだろうけど、これを書くとトップレベルで宣言したことになり Object クラスなどにも定義されてることになる。つまり、 Fuga クラスにも継承の果てに定義されていることになる。

これ結構知らなかったりするみたいなので、気をつけたいと思う。というか、 class_eval とかぽんぽん使うもんじゃないですね。。。