Jun 24 2010

Sinatra reloader

When I first started using it to write web apps a couple of years ago, Sinatra supported code reloading in development mode. That feature was dropped from the core of Sinatra at some point and we just got used to restarting the app every time we made a change whilst developing, it's not that huge an overhead, especially considering Sinatra's fast start up.

I recently had to work on a Rails codebase for a while, which reminded me that code reloading without restarting in dev mode is functionality I don't mind spoiling myself with. At the time, Abs pointed me to sinatra-reloader which I installed and used in a couple of apps and it works well. As I'm writing this, I'm also looking at Rack::Reloader, which I've never used and seems somewhat different with its own set of interesting features. Shotgun is out of the question for me, because it feels like manually restarting the app is faster than the time Shotgun takes to load everything per request.

RVM has prompted me to switch between Ruby versions more often than in the past, resulting in installing gems more frequently than I used to, which in turn brings out an OCD side of me when it comes to gems that download other gems as dependencies. That's the one thing that bugs me about sinatra-reloader and since I found myself with a bit of time on my hands, I wrote my own Sinatra reloader which I've put in this gist in case someone else finds it useful.

It works by reloading all source files and routes when it detects a change. This is less efficient than selectively reloading only code from files that have changed, although I tried it in a few of my projects without noticeable penalties. A thing to watch out for is that once a constant has been loaded, it will still be around after you delete the code that declares it. Restarting is required for such changes to take effect. I've also noticed a similar issue with classes that extend Sequel::Model - if I run a migration and don't restart, database field mappings don't get updated, because Sequel makes those mappings at the time Sequel::Model is subclassed.

In summary, if you don't mind installing a bunch of gems you're likely to never use, I recommend sinatra-reloader. If you're after code reloading which you might want to customise with a couple of lines of code on the spot to suit your particular project's needs, this can be a starting point.