Bar
モジュールとクラスになることはできません。それらは別のものです。
に変更bar.rb
するmodule Bar
か、 に変更other_bar.rb
しclass Bar
ます。
それが何であれ、それは一貫している必要があります。一方を他方に変更することはできません。問題は、どちらであるべきかということです。Bar
が他のクラスのコンテナであり、いくつかのグローバル シングルトン メソッドしかない場合は? 次に、それはmodule
です。しかし、インスタンス化できる場合、それはclass
.
はい、クラスをネストできます。これは完全に受け入れられます。
class Bar
class OtherBar
puts "running module Bar with class OtherBar"
end
end
Bar::OtherBar.new # yay!
モジュールとクラスは、適切と思われる方法で他のいずれかにネストできます。
これをすべて明確にするために、いくつかのコメント付きの例を編集してください。
module Foo
# Foo::A
class A
# simple namespaced class
end
# Foo::B, inherits from Foo::A
class B < A
# inherting from a class in the same namespace
end
# modify Foo::B
class B
# When modifying an existing class you don't need to define the superclass
# again. It will raise an error if you reopen a class and define a different
# superclass. But leaving it off is fine.
end
# nested module Foo::Inner
module Inner
# Foo::Inner::C
class C
# simple more deeply namespaced class
end
# Foo::Inner::D, inherits from Foo::A
class D < A
# inherits from a class in a parent namespace
# works because ruby looks upward in the nesting chain to find missing constants.
end
# Foo::Inner::Foo
class Foo
# simple nested class with the same name as something in a parent namespace
# This is a totally different Foo, because it's in a different namespace
end
# Foo::Inner::E, inherits from Foo::Inner::Foo
class E < Foo
# class inhereting from another class in the same namespace
# Foo::Inner::Foo is "closer" than the global Foo, so that gets found as the superclass
end
# Foo::Inner::F, which mixes in the gloabl module Foo
class F
# the :: constant prefix says to start looking in the global namespace
# so here we include the top level module Foo, and not the "closer" in namespace Foo::Inner::Foo
include ::Foo
# This is an error. This attempts to include the class Foo::Inner::Foo since thats the closest by namespace
# thing that matches the constant Foo. (you can't include classes, only modules)
# You need the :: prefix to grab the global Foo module
include Foo
end
end
end
# Z decalred in the global namespace, which inherits from the deeply nested class Foo::Inner::C
class Z < Foo::Inner::C
# Any class anywhere can inherit from any other class in any namespace.
# Just drill in!
end
# the following 2 declarations at this point would be identical
# This defines a class deep with in a namespace
class Foo::Inner::Foo::Bar < Foo::A
end
# same as above, but reopens each namespace
module Foo
module Inner
class Foo
class Bar < ::Foo::A
end
end
end
end