
プログラミング言語のRubyでプログラムを作っていて疑問に思った事がありますので
どなたかご存知の方が居れば教えてください。
Rubyにおいては同じクラス名やモジュール名であっても
モジュール内に対象クラスやモジュールを定義する事で
「モジュール名::クラス名」等と言う参照が可能になっていますよね
そこで気になったのですが、同名のクラスAとモジュールAがある場合に
(つまりクラスAの名前=モジュールAの名前)
class モジュールA::クラスB
# コンストラクタ
def initialize
@prop = クラスA.new
end
end
等と記述すると、コンストラクタの内部の記述において
クラスAの名前とモジュールAの名前が競合するので、クラスBの生成時にエラーが発生します。
この様なケースにおいて、コンストラクタの内部でクラスAのインスタンスを
正しく生成する方法はあるのでしょうか?
勿論前提として、クラスAは他のモジュールに含まれたクラスではありません。
Javaの様にパッケージ概念があって、全てのクラスについて何らかのパッケージに所属している等の
仕組みが無いので、時々この様な命名をしてしまい困る事があるので
この様なケースを回避する方法についてご存知の方が居れば、教授ください。
よろしくお願いします。
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
Rubyのモジュールやクラスは定数です。
同じ名前空間で同じ名前の定数を定義することはできません。ですから、
class A
end
module A
end
とすると、A is not a module というエラーになります。
これは、クラスとして定義した A をモジュールとして開き直そうとしています。
但し、この class A と module A が別々のファイルに記述されていて、
class A、または。module A を呼び出した場合エラーにはなりません。
なぜなら、Ruby は定数の探索をして最初に到達したものを採用するからです。
そしてご質問のケースの場合、Ruby は module A を見つけたがクラスではないので、エラーを出しています。
a = A # => エラーにはならない。
a = A.new # => エラーになる。
つまり、同一の名前空間に同じ名前のクラスとモジュールを記述することはコーディングミスです。
ファイルが分かれていれば、呼び出さない限りはエラーにはなりませんが、
これではまともなプログラムが書けません。
同じ名前を使いたければ、名前空間を分けるようにしましょう。
例えば、
# coding: utf-8
module Dog
class Voice
def play
puts "わん"
end
end
end
module Cat
module Voice
def cry
puts "にゃあ"
end
end
end
tama = "ねこ"
tama.extend Cat::Voice
johns_voice = Dog::Voice.new
tama.cry #=> "にゃあ"
johns_voice.play #=> "わん"
のようにします。
No.4
- 回答日時:
No.1,2です。
モジュールにせずにクラスの中にクラスを作るのはいかがでしょうか。
class A
def initialize
end
class B
def initialize
@prop = A.new
end
end
end
p A::B.new
No.1にも書きましたが、もしclass A::Aがあれば
::A.newで区別できます。

No.3
- 回答日時:
class クラスA
# コンストラクタ
def initialize
end
end
module モジュールA
class クラスB
# コンストラクタ
def initialize
@prop = クラスA.new
end
end
end
上記でエラーになるということですが、このエラーを解消するために、
module 汎用モジュールA
class クラスA
# コンストラクタ
def initialize
end
end
end
としては、いかがでしょうか。
つまり class クラスAを汎用モジュールの名前空間に閉じ込めます。
以下は、こちらで実行したサンプルソースです。
------------------------------------------
# coding:WINDOWS-31J
module Common
class NameA
def initialize
p "Class NameA initialize"
end
def put
p "put A"
end
end
end
module NameA
class NameB
def initialize
p "Class NameB initialize"
@prop = Common::NameA.new
end
def put
@prop.put
end
end
end
a = NameA::NameB.new
a.put
---------------------------------------
実行結果
"Class NameB initialize"
"Class NameA initialize"
"put A"
---------------------------------------
実行環境は
windows7
1.9.3p374 (2013-01-15) [i386-mingw32]
です。
No.2
- 回答日時:
実際のプログラムを書いてもらえればわかりやすいのですが、
module A
class B
def initialize
@prop = A.new
end
end
end
class A
end
p A::B.new
のような場合でしょうか?
この場合はA.newでエラーが出るのではなく、9行目のclass Aでエラーが出ます。
classとmoduleで同じ名前が使えないということです。(この場合はclass Aとmodule A)
名前の付け方に注意する必要があります。
No.1
- 回答日時:
ちょっと質問の意味が分からなかったのですが
module ModuleA
class ClassA
end
class ClassB
def initialize
@prop = ClassA.new
end
end
end
p ModuleA::ClassB.new
を実行させると、@propの中にはModuleA::ClassAのインスタンスが代入されます。
自分が属しているモジュールの中にClassAがあるのでModuleA::ClassAとなりますが、もし無ければモジュールの外側にClassAがないか探します。モジュールの外側の場合は::ClassA.newで区別できます。
それとも
module A
class A
end
class B
def initialize
@prop = A.new
end
end
end
p A::B.new
の場合でしょうか、これも全く問題はないですが。
こんな場合でしょうか
module A
end
class A::A
end
class A::B
def initialize
@prop = A::A.new
end
end
p A::B.new
の場合は
@prop = A.new
とした場合にはエラーになります。
このような書き方はあまりしないように思います。
この回答への補足
質問が判り辛くて申し訳有りません。
私が回避したいケースは下記の様なケースです。
クラスAの名前=モジュールAの名前
と言う状況において
class クラスA
# コンストラクタ
def initialize
end
end
module モジュールA
class クラスB
# コンストラクタ
def initialize
@prop = クラスA.new
end
end
end
と言うコードのクラスBのインスタンスを生成する際に
@prop = クラスA.new
の処理のタイミングで、クラスAをモジュールAと解釈してしまい
エラーが発生するのですが
それを回避する方法があれば教えて頂きたいと言う質問でした。
つまりこのクラスAと言うのは、どのモジュールにも所属していないクラスであり、ki073さんの回答していただいた最後のケースに近い状況でのエラーの回避です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) このプログラミングをどう組みますか? Googlecolabでやってるんですが、出来る方お願いします 1 2022/07/13 10:52
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- Visual Basic(VBA) VBA This Workbookモジュールを別ファイルにコピーする方法 1 2022/09/14 01:51
- Java JavaのSingletonパターンのprivateの持つ意味が分かりません。 5 2022/06/12 10:38
- MySQL 下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「名前(first name) 1 2023/06/24 13:03
- Perl Perl の外部モジュールの利用方法 3 2022/07/10 18:34
- その他(プログラミング・Web制作) pythonのプログラムについての質問です。 1 2023/05/26 10:31
- MySQL 下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「A,B組の女子の氏名のよみ。 1 2023/05/16 15:28
- ルーター・ネットワーク機器 PCをWI-FI化(現在は有線) 9 2023/01/16 08:20
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テンプレートの特殊化でコンパ...
-
インスタンス内から自分のクラ...
-
動的配列の構造体の受け渡しに...
-
Ruby on Rails 「attr_accessor...
-
VBA/GetTickCountの49.7日の境...
-
ブロック2 Ruby認定試験対策問題
-
singletonメソッドへのアクセス
-
railsチュートリアル5章の演習
-
メソッド定義の際の引数で
-
エラー・・
-
【Ruby on Rails】モデルのメソ...
-
再帰に関する質問です。
-
クラスメソッドのインスタンス...
-
プログラミングのクラス、イン...
-
Rails4でJSONのParseErrorを判定
-
PHP DB トランザクション
-
名前空間
-
Rubyのprettyprintについて
-
javaへの変換
-
Ruby バブルソート
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
クラス名やモジュール名の競合...
-
テンプレートの特殊化でコンパ...
-
class roomとclassroom どちら...
-
HSTLやSSTL等のI/Oピン
-
Rails AR 深い階層のテーブル参照
-
What class are you in? には何...
-
rails3初心者 年齢を表示する
-
redirect先でredirect元の変数...
-
No route matches [GET] "/post...
-
変数の隠蔽とは?
-
syntax error 一行で書くと
-
c#のマクロ定義について
-
railsのform_forの使い方
-
Rubyについて質問です
-
2つのクラスがお互いのポイン...
-
【ruby】【文法】スパークラス...
-
メソッド定義の構文のdefって
-
「arg」は何の略?
-
教えてください。vb5.0
-
get() と find() の違いについて
おすすめ情報