What are the criteria for using a module over a class in Ruby?

I am reading a ruby ​​book. Looking at the code below

module Destroy def destroy(anyObject) @anyObject = anyObject puts "I will destroy the object: #{anyObject}" end end class User include Destroy attr_accessor :name, :email def initialize(name,email) @name = name @email = email end end my_info = User.new("Bob"," Bob@example.com ") puts "So your name is: #{my_info.name} and you have email #{my_info.email}" user = User.new("john"," john@example.com ") user.destroy("blah") 

I could just create another method inside my class. Why do I want to do this? Why do I want to use a module? This is not like embedding this in other classes, it is easier than just using regular inheritance.

+6
source share
3 answers

You can think of the module and the methods and constants inside it as providing functions and utility functions that you can include in other objects as you wish. For example, if you want to use the destroy function in Foo and Bar objects, you would do the same:

 class Foo include Destroy # other code below end class Bar include Destroy # other code below end 

Now any Foo or Bar object has access to all methods or constants inside the destruction.

Modules define a namespace, a sandbox in which your methods and constants can play, without worrying about other methods and constants attacking them. ruby docs goes deeper about this and includes a good example when you want to use it, as shown below:

 module Debug def whoAmI? "#{self.type.name} (\##{self.id}): #{self.to_s}" end end class Phonograph include Debug # ... end class EightTrack include Debug # ... end ph = Phonograph.new("West End Blues") et = EightTrack.new("Surrealistic Pillow") ph.whoAmI? » "Phonograph (#537766170): West End Blues" et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow" 

In this example, every class that includes Debug has access to the whoAmI? and other methods and constants that Debug includes, without having to override it for each class.

+3
source

Some programming languages, such as C ++, Perl, and Python, allow one class to inherit from several other classes; which is called multiple inheritance. Ruby does not support multiple inheritance. This means that each class can inherit only one class. However, there are times when a class wins by acquiring methods defined in several other classes. This was made possible through the use of a design called a module.

A module is somewhat similar to a class, except that it does not support inheritance and does not instantiate. It is mainly used as a container for storing several methods. One way to use the module is to use the include or extend statement inside the class. Thus, the class gets access to all methods and objects defined in the module. They say the module is mixed in the class. So mixin is just a module included in the class. One module can be mixed in several classes, and one class can be mixed in several modules; In this way, any restrictions imposed by the Ruby single inheritance model are eliminated by the mixin function .

Modules can also be used for namespaces. This is explained in this post on the Practicing Ruby website .

+2
source

You write the module in the same file as the class, but not necessarily inside the class, but in any case.

For me there are 3 reasons to use the module (more details here ):

  • Modules provide a namespace and prevent name conflicts.
  • Modules implement the mixin tool.
  • When you have a very complex and dense class, you can break it into modules and include them in the main class.

Your example is pretty simple, it would be wiser to write a method in the class itself, but try to imagine a complex scenario.

0
source