Can a Ruby module be described as a singleton class?

后端 未结 3 519
独厮守ぢ
独厮守ぢ 2021-01-19 09:38

I\'m trying to understand the purpose of a Ruby module from a design pattern perspective.

Is a Ruby module essentially just a class that is only initialized once?

相关标签:
3条回答
  • 2021-01-19 10:19

    A class is a module but a module is not a class. Module is literally the superclass of Class. If you know OOP, that's all you need to know.

    Ruby modules are best used as namespaces and used in mixins.

    0 讨论(0)
  • 2021-01-19 10:22

    A ruby class is a module you can make instances of. Like a class, a module can have methods, but you cannot make an instance of a module. That's the only difference between them.

    In practice, modules are commonly used for:

    • Name spaces
    • Mixins
    • To hold functions

    Name Space

    Here's an example of a module used as a name space:

    module MyLib
      class Foo
      end
      class Bar
      end
    end
    

    The full name of these classes is MyLib::Foo and MyLib::Bar. Because they are contained in a namespace (which presumably is unique), the names Foo and Bar cannot conflict with a Foo or Bar defined in your program or in another library.

    Mixin

    Here's a module used as a mix-in:

    module Mixin
      def foo
        puts "foo"
      end
    end
    

    Since you can't make an instance of the Mixin module, you get access to foo by including (mixing in) the module:

    class MyClass
      include Mixin
    end
    
    MyClass.new.foo    # => foo
    

    Functions

    Like a class, a module can hold functions that do not operate on any instance. To do that, you define class methods in the module:

    module SomeFunctions
      def self.foo
        puts "foo"
      end
    end
    

    A class method defined in a module is just like a class method defined in a class. To call it:

    SomeFunctions.foo    # => foo
    
    0 讨论(0)
  • 2021-01-19 10:25

    Modules have two uses in Ruby: namespacing of constants and as mixins.

    Namespacing of constants simply means that in

    FOO = 1
    
    module Bar
      FOO = 2
    end
    
    module Baz
      FOO = 3
    end
    

    there are three different FOOs in three different namespaces: one in the global namespace (which is actually Object), one in Bar and one in Baz.

    The more interesting use case is mixins: a mixin is basically a class which is parameterized over its superclass. Or, to put it another way: a mixin is a class that can appear multiple times in the inheritance graph, each time with a different superclass.

    Contrast this with multiple inheritance: in multiple inheritance, a class can only appear once in the inheritance graph, but it may have multiple superclasses. A mixin may appear multiple times in the inheritance graph, but each occurrence has only one superclass.

    In particular, what happens in Ruby when you mix a module M into a class C is that an actual class (a so-called include class) is created (let's call it M′) whose method table, constant table and variable table pointers point to M's method table, constant table and variable table, and that class M′ becomes C's superclass with the old superclass becoming M′'s superclass.

    0 讨论(0)
提交回复
热议问题