
プログラミング言語の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ランキング
-
WIN11にオフイスを複数入れるこ...
-
Ruby require ライブラリー
-
ruby while式
-
ruby loopメソッド 変数(再喝)
-
pythonエラー
-
Accessで文字列のバイト数読み込み
-
教えてください
-
7セグメント LED ディスプレイ ...
-
100万件越えCSVから条件を満た...
-
ruby OpenURI::Meta
-
パソコンのスクリーンセーバー...
-
ビーリアルのユーザー名を変え...
-
pandasでsqlite3にテーブル作成...
-
(再質問)エクセルのマクロボ...
-
文字コードのエラー
-
ruby 配列
-
ruby loopメソッド 変数
-
ruby クラス・オブジェクト・イ...
-
ルビー言語 ライブラリー 追記
-
ruby raise句
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
What class are you in? には何...
-
クラス名やモジュール名の競合...
-
Rubyの正規表現を引数に
-
住所の追加について
-
動的配列の構造体の受け渡しに...
-
プログラミングRubyについての...
-
No route matches [GET] "/post...
-
HSTLやSSTL等のI/Oピン
-
Ruby
-
次のDelphiプログラムで
-
Visualurubyのラジオボタンにつ...
-
pythonのerrorコード
-
【ruby】特異クラスを使って,Fi...
-
【ruby】【文法】スパークラス...
-
【ruby】クラスCGIを改造して、...
-
パイソンのクラス
-
syntax error 一行で書くと
-
Ruby Vectorの===変更の問題
-
class roomとclassroom どちら...
-
redirect先でredirect元の変数...
おすすめ情報