Tomorrow's Chance

社会人なりたてのエンジニア奮闘記

Rubyにおけるincludeと定数の扱い

Rubyはクラスの継承について特異メソッド等様々な機能が存在しているイメージを持っています。例えばModuleなりClassなりをIncludeした場合にPHPでいうところのconstで定義したクラス内定数を「クラス名::定数名」なんて書かずに「定数名」だけで参照することが可能だったりします。

 

そうすると定数名が被った時どうなるんだろうと素朴に疑問が浮かびました。

例えば

 

module Test

  CONST = 'hoge'

end

 

module Test1

  CONST = 'hogehoge'

end

 

class TestClass

  include Test

  include Test1

 

  def DispConst

    p  CONST

  end

end

 

TestClass.new.DispConst

 

と別々のModuleで同一の定数を定義し、両方Includeした場合どうなるのだろうかと

結果はこうでした

 

'hogehoge'

 

Test1の定数が出力されました。どうも後からincludeしたもので上書きされるようです。

ちなみに上記コードの中でTestのCONSTを参照するには

 

p Test.CONST

 

といった感じでPHPのクラス内定数の参照のようにクラス名を明示することで可能のようです。また、

 

class TestClass

  CONST = 'testclass'

  include Test

  include Test1

 

  def DispConst

    p  CONST

  end

end

 

 

このように、呼び出すクラス内にも定義されていた場合は

 

'testclass'

 

と、includeを無視してクラス内の定義が出力されました。

Rubyは少ない記述量で済みますがこういう微妙な書き方の違いで結果が変わるケースが数多くありそうでオブジェクトの管理をしっかりしないと後々危険な印象を持ちました。