Mixins are the Ruby way to eliminate the need for multiple inheritance. In short, a class can "mixin" multiple modules, which in practice means that it gains either the instance or class methods defined in the mixed in module, depending on how it was mixed in.
This has some benefits. When a an objects method gets called, it is clear in what order the interpreter will search for that method (see a more detailed discussion), thereby avoiding the "Deadly diamond of death" problem.Let's look at some code to clarify this.
module A def stuff puts "Hi, I'm module A" end end module B def stuff puts "Hi, I'm module B" end def is_a?(_class) "B#is_a?" end end class First include A include B end class Second include B include A end class Third def stuff puts "Hi, I'm class Third" end include A include B end class ThirdChild < Third end First.new.stuff # Hi, I'm module B Second.new.stuff # Hi, I'm module A Third.new.stuff # Hi, I'm class Third puts ThirdChild.new.is_a?(First) # B#is_a?
Finally, the instance of ThirdChild returns the "B#is_a?" string when its is_a? method is called. It is easy to jump to the conclusion that it should call Object#is_a? and return false. However, it's first ancestor, Third, has mixed in module B, and has therefore overridden the Object#is_a? method.
Mixins are a powerful tool, in particular to DRY up code. A common example of its benefits is to mixin the Comparable module and get several comparison methods by implementing a single method (<=>). But mixins should be used with care.
Whenever you mixin a module, you are increasing the complexity and surface of that object. Added complexity means that it is more likely to contain bugs. You also need to think hard about whether the mixin violates the single responsibility principle (and if so, is the violation worth the benefits?).