Ruby Techniques Revealed: Autoload

By Peter Cooper

There's plenty of stuff in Ruby that I've either not noticed before, noticed but forgotten about, or otherwise failed to realize the utility of. Add to that all the awesome Ruby tricks and techniques I'm seeing in people's code over on Github lately and.. we need a new series here: Ruby Techniques Revealed!

Disclaimer: I'm not promising you won't already know about anything I "reveal." A lot of you are far better than me at knowing all of Ruby's dark corners. I'm just going to shine a spotlight in the direction of things I don't see used very often that I think are cool.

Autoload - Load stuff only when it's needed

I was going through the source for Thin and noticed that instead of using require , Marc-Andre Cournoyer was using a method called autoload to load thin's constituent parts. Specifically:

autoload :Command , ' thin/command ' autoload :Connection , ' thin/connection ' autoload :Daemonizable , ' thin/daemonizing ' autoload :Logging , ' thin/logging '

This intrigued me so I hit Google and came across a little demo of autoload by Mike Subelsky. autoload works in a similar way to require , but it only loads the file specified when a constant of your choosing is accessed/used for the first time. This constant would usually be the name of the class provided by the other source file (but it doesn't have to be, as Mike demonstrates).

Let's say you have a file called mylibrary.rb containing the following code:

puts " I was loaded! " class MyLibrary end

Now, from irb , let's use require to load the "library":

irb(main):001:0> require 'mylibrary' I was loaded! => true

Because require works straight away, the puts method gets executed immediately. So let's restart irb and see what happens if we use autoload instead:

irb(main):001:0> autoload :MyLibrary, 'mylibrary' => nil irb(main):002:0> MyLibrary.new I was loaded! => #<MyLibrary:0x0b1jef>

The puts method doesn't get executed until we try and use MyLibrary . autoload has prevented the loading of mylibrary.rb until we really needed it.

Detecting Autoloadable Classes

If you want to detect whether a certain class is awaiting autoloading, you can check, like so:

autoload :X, 'x' puts "X is awaiting loading" if autoload?(:X)

Just beware ye threads..

Further Googling led me to some interesting discussions about autoload . Back in December 2008, a whole group of Ruby luminaries got into a discussion about autoload's issues with threads. Turns out that even though several projects have been adopting autoload in anger recently, there are some concerns surrounding how thread safe autoload is. The proposed solution is to have a mutex between all autoloads, but I haven't yet established how far work on this (if any) has gone.