ruby模块和类在结构中的名称相同

我的一个项目中有如下文件夹结构:

  • LIB
    • bar.rb
    • 酒吧
      • other_bar.rb
      • another_bar.rb
      • next_bar.rb

bar.rb

require File.expand_path(File.dirname(__FILE__) + "/bar/other_bar.rb") class Bar puts "running BarBase" end 

酒吧/ other_bar.rb

 module Bar class OtherBar puts "running module Bar with class OtherBar" end end 

如果我现在运行ruby bar.rb我得到这个:

运行带有类OtherBar的模块栏
bar.rb:3:in”:Bar不是类(TypeError)

我想要一个类似于rails模型inheritance结构的结构。 我怎样才能解决这个问题? 据我所知,ruby并不支持开箱即用。 这种情况有解决方法吗?

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 

只需使用class Bar而不是module Bar 。 在Ruby中,可以重新打开并添加类。