gem install railsalone installs 27 gems by default (a clean install of 3.2.0 on MRI) and one most likely adds a whole bunch of others as the application evolves. Effectively managing those dependencies slightly became rocket science and Bundler is undoubtedly doing a great job safely landing on the moon every time we change a dependency ingredient.
And one day you decide to bring in a web server for development. Maybe you're even confident about the production server requirements already. So you uncomment the
gem 'unicorn', hey it's already there! Add
gem 'thin'for development and
Seems about right, but wait let's think about that for a second. We've specified Unicorn as a dependency for our application, every time we run a rake task, console,
thinor any other
bundle execit gets loaded (with a require). If you don't believe me just
rails cand see if the
Unicornconstant is defined, in development
Thinshould be present as well. Feels a bit wrong (unless of course your code depends on the server API for whatever reason). Let's blame Bundler, but wait turns out it's his job to go through your gem dependencies and load them. Maybe there's someone else to blame after all, sure it was really easy to uncomment a line and hit
bundle installin the same second. Moral lesson taken: we should think (at least) twice whenever editing
Let's roll right away, a quick second think and we're at :
Much better, see we're telling bundler that it is a dependency but should not be required, servers usually come with they very own commands to be run (and load them).
This is also crucial when declaring JRuby servers such as
gem 'trinidad'as your dependencies (otherwise you might end up with a scary error such as: java.lang.NoClassDefFoundError: javax/servlet/ServletContext). And actually, for more complicated deployments declaring a server dependency may just be a little unnecessary and counterproductive. But I'll rather try to explain all that in a following post.