ruby 2.5で変更されたtoplevel constant lookupの挙動
こういうコードがあったとして
class Foo; end class Bar; end p Foo::Bar #=> Bar
ruby 2.4まではwarning: toplevel constant Bar referenced by Foo::Bar
を出しつつFoo::Bar
はBar
を返す。
これはrubyの定数探索が継承関係を遡って探すという仕様と、トップレベルで定義された定数がObjectに所属する、という仕様によるもの。わかりやすく書くとこういう感じ。
class Foo < Object; end Object::Bar = 1 p Foo::Bar #=> 1
Foo::Bar
としたときFoo
にはBar
がないので、次にFoo
の継承関係を辿って親クラスのObject
からBar
を探す。するとObject::Bar
が見つかるのでObject::Bar
を返す。
2.5だとこれがエラーになるように変更された。
class Foo; end class Bar; end p Foo::Bar #=> NameError: uninitialized constant Foo::Bar