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中,可以重新打开并添加类。