As you might have heard inheritance is evil. I won’t argue, but indeed often inheritance is used improperly. The only legitimate usage of inheritance is creating more specific entity, not sharing the code. In this blog post I’ll assume that inheritance is evil when used for code sharing.
Mixins are another syntax for inheritance
TL;TD And they are used for code sharing, thus mixins are evil. Indeed, in Ruby included module becomes an implicit superclass with all perks of inheritance. And this can be abused.
1) super and method overriding
module One def func puts "in module" end end class Two include One def func puts "in class" super end end # take a look at object hierarchy Two.ancestors [  Two < Object,  One, # implicit superclass  Object < BasicObject,  PP::ObjectMixin,  Kernel,  BasicObject ] # call a function Two.new.func in class in module # <- yes, you can call `super`
You can also include many modules with the same methods:
module One def func puts "in one" end end module Two def func puts "in two" end end class Three include One include Two def func puts "in class" super end end Three.ancestors [  Three < Object,  Two,  One,  Object < BasicObject,  PP::ObjectMixin,  Kernel,  BasicObject ] Three.new.func #=> what do you expect here?
The last example can be an interview question. It requires knowledge of how modules and inheritance actually work.
2) they have access to instance variables of a class
Being just a superclass, included module can access private instance variables of a child:
module One def func puts @var end end class Two include One def initialize @var = 'hello' end end Two.new.func #=> hello
Same is true for private methods.
Now a developer can abuse mixins and make his code an unreadable mess. With good intentions, of course. For example, why not include 10 modules in 1 class? Now I have a “small” class and everything else spread across 10 entangled modules. Did I mention that you can call methods of another module from withing a module? Multiply this possibility by method overriding and instance variables and here comes a mess.
Is this really bad? Yes! You should keep you classes and method small, but when you split a big class into modules you make things worse. Now you have not only a big class, but a big class scattered across multiple files making it harder to read.
Mixins are just cheaty syntax for inheritance intended for code sharing. Avoid them if you can. Prefer composition instead. This is true for any kind of inheritance, and especially for mixins.
In my opinion, the only legit case for mixins is when your module has no dependency on a class where it’s included. But even if it’s true for now doesn’t mean other developers cannot add dependency later. There is no barrier.