[僕] クラス名と名前空間かぶるとダメ?

僕ト云フ事

たろマークはてなブックマーク

2009年11月28日

[ruby] クラス名と名前空間かぶるとダメ?

Foo::Bar というクラスのクラスメソッドを Fuga::Foo のメソッドの中で使おうとしたら、Fuga::Foo::Bar なんてクラス無いよと怒られたのでメモ。

追記

IRC で lyokato さんが答えを教えてくれました。

lyokato: ::Foo::Barにしたら呼べるよ!
module Fuga
  class Foo
    def hogera()
      p ::Foo::Bar.test # 頭に :: をつける
      'Fuga::Foo.hogera'
    end
  end
end
 
foo = Fuga::Foo.new
p foo.hogera

これで上手く行きました。
実行結果

"Foo::Bar.test"
"Fuga::Foo.hogera"

どうも呼び出したコンテキストの階層から探しに行って、Fuga::Foo に Foo がマッチしちゃうらしい。頭に :: つけるとトップレベルとして認識されるのね。

元の疑問

環境

  • Mac OS X 10.5.8
  • ruby 1.9.1p129 (2009-05-12 revision 23412) [i386-darwin9]

test というクラスメソッドを持った、Foo::Bar と言うクラスを作ります。

module Foo
  class Bar
    def self.test()
      'Foo::Bar.test'
    end
  end
end

Foo::Bar を Fuga::Foo の hogera で使おうとします。

module Fuga
  class Foo
    def hogera()
      p Foo::Bar.test
      'Fuga::Foo.hogera'
    end
  end
end
 
foo = Fuga::Foo.new
p foo.hogera

すると NameError が >_<

hoge.rb:12:in `hogera': uninitialized constant Fuga::Foo::Bar (NameError)
        from hoge.rb:19:in `
'

でも、クラス名を変えてあげると大丈夫。

module Fuga
  class Awawa
    def hogera()
      p Foo::Bar.test
      'Fuga::Awawa.hogera'
    end
  end
end
 
awawa = Fuga::Awawa.new
p awawa.hogera

実行結果

"Foo::Bar.test"
"Fuga::Awawa.hogera"

なんでだろ。まだ、よくわかってないですね。
あと、やたら名前空間区切りたくなるんだけど、おかしいのかも。作ろうとしてるの、module じゃないからなぁ。

blog comments powered by Disqus