Ruby's quirky load order for mixins

posted by Ayush Newatia
17 May, 2021



Ruby modules are a great way to define mixins. This construct offers a way to share logic using composition.

As it is usually the case with Ruby, there’s two ways of mixing (or includeing) ruby modules into your class:

class Post
  include Categorizable
  include Copyable
end

OR

class Post
  include Categorizable, Copyable
end

At first glance you might think those two syntax are identical, but Ruby has a quirk that isn’t immediately obvious. To demonstrate this, let’s print out a line from those two module when they’re included:

module Categorizable
  def self.included(base)
    puts "Categorizable included"
  end
end

module Copyable
  def self.included(base)
    puts "Copyable included"
  end
end

Now we can see the what’s going on under the hood when these modules are included.

class Post
  include Categorizable
  include Copyable
end

Post.new # =>
# Categorizable included
# Copyable included
class Post
  include Categorizable, Copyable
end

Post.new # =>
# Copyable included
# Categorizable included

As demonstrated by those above snippets, the load order of the modules in the two examples is different. The first syntax option loads from top to bottom as you’d expect. The second example however load from right to left.

In most cases this shouldn’t matter as mixins should usually be independent of each other. However it’s easy to get tripped up by this if a module depends on another module being loaded.

Here’s an example from HEY shared by DHH on how to manage this quirk without making a mess:

It’s usually best to use a combination of the two syntax as demonstrated in the image above. This makes any dependencies between the mixins blatantly obvious to anyone reading the code.

I love Ruby and it’s weird quirks like this; but it’s always good to know when something subtle like this might trip you up!