Ruby

Rubyで定数が定義される場所はネスティングによって決まる

はじめに

この記事は、以前私が書いた"ブロックを定数で定義するときはスコープに気をつける"というタイトルの記事を大幅に修正したものです。
扱う内容がかなり変わってしまったため別記事にするべきかとも思いましたが、頂いたコメントが非常に示唆に富み、消してしまうのはもったいないと感じたので、同じ記事に修正という形を取らせていただきました。
コメントで指摘を下さった皆さま、ありがとうございました。

結論

定数の定義される場所は、定義された時のネスティングによって決まる。

class_evalでクラスを開いてその中に定数を定義した際、意図した場所に定数が定義されていないことから、定数はどこに定義されるのか疑問が湧きました。

class MyClass; end

MyClass.class_eval do
  CONST = "Fuga"
end

上記のように定数を定義すると、初心者の私はMyClass::CONSTに定義されていそう!と思いました。
が、実際には、、、

pry(main)> MyClass::CONST 
#=> NameError: uninitialized constant MyClass::CONST

pry(main)> CONST
#=> "Fuga"

???Ruby何一つわからない…となってしまったのですが、定数の定義場所はネスティングによって決まるということを教えてもらい、謎が解けました。
以下、順を追って説明します。

ネスティングとは

ネスティングとは、すごくざっくり言ってしまうと"構文的な構造上のコードの区分"で(厳密な定義と間違っていたらごめんなさい)、
class識別子を使用したクラスの定義とmodule識別子を使用したモジュール定義によって切り替わり、Module.nestingによって確認できます。

class MyClass
  p Module.nesting
end

#=> [MyClass]

このネスティングに対応する位置に定数は定義されています。

CONST_TOP = "Foo"

pry(main)> p Module.nesting
#=> []
# ネスティングがトップレベルだと空

module A
  CONST_A = "Bar"
  p Module.nesting
  #=> [A] ネスティングが切り替わる

  class B
    CONST_B = "Hoge"
    p Module.nesting
    #=> [A::B, A] ネスティングが切り替わる
  end
end

pry(main)> CONST_TOP
#=> "Foo"

pry(main)> A::CONST_A
#=> "Bar"

pry(main)> A::B::CONST_B
#=> "Hoge"

#ネスティングに対応した位置に定数が定義されている!

それでは、先ほどの例に戻りclass_evalでクラスを開いて定数を定義してみると、その定数はどこに定義されるのでしょうか?

class MyClass; end

MyClass.class_eval do
  p Module.nesting
  #=> [] ネスティングは切り替わっておらず、トップレベルのまま!
  CONST = "Fuga"
end

# class_evalのブロックの中に入ってもネスティングは切り替わっておらず、トップレベルのまま。
# ということは、定数CONSTはトップレベルのネスティングの位置に定義されているはず!

pry(main)> CONST
#=> "Fuga"
# なるほど〜

MyClass::CONSTに定数が定義されているのでは?と思ってしまうのは、class_evalを使うとコンテキストがMyClassに切り替わっているためなんですね…

MyClass.class_eval do
  p self
  #=> MyClass
  # コンテキストがMyClassに切り替わるため(selfがMyClassに切り替わるため)、
  # 見た目的にMyClass::定数名の位置に定数が定義されていると勘違いしてしまった…
end

まとめ

定数の定義場所はネスティングによって決まる(コンテキストは関係無い)ため、定数を定義する際はネスティングに注意しよう!という話でした。

参照
rubyリファレンスマニュアル
メタプログラミングRuby