Autoloading Constants In Ruby

Whilst reading some old Rails code I came across this:

module Ember
  module Handlebars
    case Sprockets::VERSION
    when /\A2\./
      autoload :Template, 'ember/handlebars/templates/sprockets2'
    when /\A3\./
      autoload :Template, 'ember/handlebars/templates/sprockets3'
    else
      raise "Unsupported sprockets version: #{Sprockets::VERSION}"
    end
  end
end

I hadn’t seen the autoload method before but looking at the code I could figure out what it enabled the library’s author to achieve. They can provide two different implementations of a class called Template. One designed for use with Sprockets v2 and the other with v3. Which one gets loaded depends on the version of Sprockets.

autoload is a standard Ruby method defined on Module and it takes the name of a constant and a path to a file. The file will be loaded the first time the constant is referenced.

So if for example in ‘ember/handlebars/templates/sprockets2’ we have the following class defined:

module Ember
  module Handlebars
    class Template
      raise "Hey"
    end
  end
end

and in ‘ember/handlebars/templates/sprockets3’ we have the same class defined but with a different implementation:

module Ember
  module Handlebars
    class Template
      raise "Hi there"
    end
  end
end

If Sprockets::VERSION returns 2 then the “Hey” class will be loaded the first time Ember::Handlebars::Template is referenced and the error will be raised. If the version is 3 then “Hi there” will get raised.