I have a folder structure like the following in one of my projects:
bar.rb
require File.expand_path(File.dirname(__FILE__) + "/bar/other_bar.rb")  class Bar   puts "running BarBase" end   bar/other_bar.rb
module Bar   class OtherBar     puts "running module Bar with class OtherBar"   end end   If I now run ruby bar.rb I get this:
running module Bar with class OtherBar
bar.rb:3:in `': Bar is not a class (TypeError)
I'd like to have a similar structure to a rails model inheritance structure. How can I fix this? So far as I know ruby does not support this out of the box. Is there a workaround for such a situation?
What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).
In Ruby, modules are somewhat similar to classes: they are things that hold methods, just like classes do. However, modules can not be instantiated. I.e., it is not possible to create objects from a module. And modules, unlike classes, therefore do not have a method new .
Actually, Ruby facilitates the use of composition by using the mixin facility. Indeed, a module can be included in another module or class by using the include , prepend and extend keywords.
Namespace in Ruby allows multiple structures to be written using hierarchical manner. Thus, one can reuse the names within the single main namespace. The namespace in Ruby is defined by prefixing the keyword module in front of the namespace name. The name of namespaces and classes always start from a capital letter.
Bar can't be a module and a class, they are different things.
Change bar.rb to module Bar or change other_bar.rb to class Bar.
Whichever it is, it has to be consistent.  You can't change one to the other. The question is which should it be? If Bar is a container for other classes and only has a few global singleton methods? Then it's a module. But if it can be instantiated, then it's a class.
And yes, you can nest classes. This is totally acceptable:
class Bar   class OtherBar     puts "running module Bar with class OtherBar"   end end  Bar::OtherBar.new # yay!   Modules and Classes can be nested inside either other in any way you see fit.
Edit with some commented examples to help clear this all up:
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 
                        Just use class Bar instead of module Bar. In Ruby, classes can be reopened and added to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With