Mixin modules

In Ruby, a Class can have methods. Similarly, a Module can also have methods.

module Hello
   def name
       puts "hello bobo"
   end
end

However, we can’t call new on a Module. A module needs to be mixed in with a class. In other words, we need to put the module in a class and then we need to instantiate that class. Then, that instance will have access to the methods defined in the module.

class People
   include Hello
end

p1 = People.new
p1.name

putting this method in a module. Now, any class that needs to calculate speed can include the module and can do the speed calculation.

module Color
  def calculate_Color
    puts "current1color is now visible on your dashboard"
  end
end

class Book
  include Color
end

class Phone
  include Color
end

class Mouse
  include Color
end

car1 = Book.new
car1.calculate_Color

car2 =Phone.new
car2.calculate_Color

rocket1 =Mouse.new
rocket1.calculate_Color

have a method defined by the same name in both the class as well as in the module. In that case, which method will Ruby choose? The answer depends on what path Ruby takes for looking up methods.

module Info
  def name
    puts "bobo"
  end
end

class Person
  include Info
  def name
    puts "name from the Person class"
  end
end

p1 = Person.new
p1.name   // name from the Person class

In large programs, we cannot remember the order in which Ruby will look up methods. It turns out, we don’t need to remember that. ask Ruby to give us that order.

module Info1
  def name
    puts "bobo"
  end
end

module Info2
  def name
    puts "bozai"
  end
end

class People
  include Info1
  include Info2
end

puts Person.ancestors // [People, Info2, Info1, Object, Kernel, BasicObject]
puts Person.included_modules // [Info2, Info1, Kernel]

Let’s see what happens if we change a module after it has been included.

module Info
  def name
    puts "bobo"
  end
end

class Person
  include Info
end

module Info
  def name
    puts "bozai"
  end
end

p1 = Person.new
puts p1.name // bozai

As we can see, the result is bozai. Do not think that including a module is equivalent to copy pasting all the module code into the class. Including a module does not work like that.

Including a module is more like setting up a link in the method lookup. When p1 is looking for the method name, then first Ruby will check if class Person has any instance method called name. The answer is No.

Then, Ruby will check if class Person includes any modules. The Answer is Yes. Module Info is included.

Then, Ruby checks if that module has a method called name. Answer is Yes. Now, Ruby executes that method.

That is why, we can make changes to the module even after they are included in a class and the updated method will be picked up.