[#44431] コンストラクタの引数について&インスタンス変数の持ち方について — Akira Hayakawa <ruby@...>

度々オブジェクト指向についての質問ですいません。

17 messages 2008/01/04
[#44433] Re: コンストラクタの引数について&インスタンス変数の持ち方について — Yukihiro Matsumoto <matz@...> 2008/01/04

まつもと ゆきひろです

[#44469] pdf 作成 ライブラリ — "Luiz Aoki" <luizruby@...>

はじめまして、青木ルイスと申します、

14 messages 2008/01/12
[#44479] ファイル出力時のprintについて — m-hatake@... 2008/01/16

畠山と申します。

[#44483] format %g の丸めについて — 山崎雄介 <y-yamasaki@...>

山崎(ゆ)です。

14 messages 2008/01/16

[ruby-list:44528] Module内Methodの名前空間

From: "Shingo Hagiwara" <rindou@...>
Date: 2008-01-23 02:38:18 UTC
List: ruby-list #44528
萩原と言います。

初歩的な質問で申し訳ないのですが、調べても分からなかったのでここで質問させてください。

なお、RubyのVersionは1.8.6 p0です。

$ ruby --version
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-cygwin]


本題ですが、「名前空間を分けてModuleのMethodを使いたいな」と思い、includeせずに他のクラス内でModuleのMethodを使おうとしました。それで以下のようなコードを書きました。

Code(1):
module ModuleA
  module ModuleAA
    CONS=1
  end
  include ModuleAA #Module内Moduleは同じ名前空間

  def methodMA()
    p "methodMA"
  end

  def methodMB()
    p "methodMB"
  end
end

class ClassA
  def methodCA01()
    p ModuleA::ModuleAA::CONS
  end

  def methodCA02()
    ModuleA::methodMA()
  end
end

classA = ClassA.new
classA.methodCA01()
classA.methodCA02()

この場合、
$ ruby testcode.rb
1
testcode.rb:XX:in `methodCA02': undefined method `methodMA' for
ModuleA:Module (NoMethodError)

のように、「classA.methodCA02()」怒られました。「classA.methodCA01()」は動くのに僕には不思議でした。
Moduleはインスタンスなのにおかしいなぁ……とも思ったのですが、クラスメソッドのようなものかなと納得し、クラスメソッドと同じようにModule名をMethodに付けて以下のように書き換えました。

Code(2):
module ModuleA
  module ModuleAA
    CONS=1
  end
  include ModuleAA  #Module内Moduleは同じ名前空間

  def ModuleA::methodMA()
    p "methodMA"
  end

  def methodMB()
    p "methodMB"
  end
end

class ClassA
  def methodCA01()
    p ModuleA::ModuleAA::CONS
  end

  def methodCA02()
    ModuleA::methodMA()
  end
end

classA = ClassA.new
classA.methodCA01()
classA.methodCA02()

すると、

$ ruby testcode.rb
1
"methodMA"

のように無事に動きました。次に、「ModuleA::methodMA()でmethodMB()(methodMB()はModuleAのPrivate扱いにしたい)を使いたい」と思い、

Code(3):
module ModuleA
  module ModuleAA
    CONS=1
  end
  include ModuleAA  #Module内Moduleは同じ名前空間

  def ModuleA::methodMA()
    p "methodMA"
    methodMB()
  end

  def methodMB()
    p "methodMB"
  end
end

class ClassA
  def methodCA01()
    p ModuleA::ModuleAA::CONS
  end

  def methodCA02()
    ModuleA::methodMA()
  end
end

classA = ClassA.new
classA.methodCA01()
classA.methodCA02()

と書いたら、今度は

testcode.rb:XX:in `methodMA': undefined method `methodMB' for
ModuleA:Module (NoMethodError)

と怒られました。同じModule内でのMethod呼び出しなのにと、個人的には分からなくなりました。

そこで、「Moduleの中身は常にTopから辿らないと駄目なんだ」と思って、

Code(4):
module ModuleA
  module ModuleAA
    CONS=1
  end
  #includeを止めてみる
  #include ModuleAA

  def ModuleA::methodMA()
    p "methodMA"
    p ModuleAA::CONS  #ModuleAから辿ってない
  end
end

class ClassA
  def methodCA01()
    p ModuleA::ModuleAA::CONS
  end

  def methodCA02()
    ModuleA::methodMA()
  end
end

classA = ClassA.new
classA.methodCA01()
classA.methodCA02()

と書いて、ModuleA::ModuleAA::CONSへのアクセスを、ModuleAA::CONSでしてみるように、書いてみたのですが、僕の予想とは裏腹に

$ ruby testcode.rb
1
"methodMA"
1

と動いてしまいました。

つまり、Module というのは、Module01::Module02::...::ModuleNとなってても、ModuleNとなるのか?と思い

  def methodCA01()
    p ModuleA::ModuleAA::CONS
  end

を

Code(5):
  def methodCA01()
    p ModuleAA::CONS
  end

と書いても当然動きません。この辺の名前空間についてどういう呼び出し規則、名前空間となっているか、そして僕がどう下手をこいているのかできれば是非お教え下さい。
長くてすいません。それでは。

In This Thread

Prev Next