Why RVM caused DateTime arithmetic headaches

Here’s a bit of DateTime arithmetic in our Rails 4 codebase.

time_lapse = (DateTime.now - start_date)

start_date is a DateTime object too. Expected result of the subtraction?

irb> time_lapse

=> (53939497/86400000000)

irb> time_lapse.class

=> Rational

Perfect. This is as expected.

However, on one of our development machines, here is what we saw for the same DateTime subtract operation:

irb> time_lapse

=> 0

irb> time_lapse.class

=> Fixnum

Huh? What? Why the different resulting object?

Same version of Ruby (including patch level). Same version of Rails. All gems same. No core extensions and/or monkey patches. Same version of operating system (OS X Mavericks).

After much burrowing into the nether reaches of Rails, and all logically-related libraries, we came up empty. A passing comment about how ‘fundamental’ this problem appeared caused us to dig even deeper.

At PetroFeed, we’ve left Ruby app environment management up to the personal preference of the individual developer. Some of us started out in Ruby-land with RVM (http://rvm.io/) while some of us with rbenv (http://rbenv.org/).

Our DateTime issue was seen on a machine with rubies installed via RVM. rbenv-managed environments didn’t see the trouble.

It turns out the ‘default’ installation path of RVM nowadays is to use pre-canned binaries for an OS, rather than compile from source. When I discovered this, I was mildly troubled. I know that early RVM compiled from source by default, but that appears to have changed somewhere along the way.

After nuking the installed ruby and all associated gemsets via,

rvm remove --gems ruby-2.x.x-pxxx

a reinstall with the disable-binary switch forces RVM to recompile from source.

rvm install --disable-binary ruby-2.x.x-pxxx

Voila. Problem solved. While I can’t speak to the deep, deep underlying interplay between core Ruby objects and OS data type handling, we hope this helps other dev teams facing similar inconsistency.

Meanwhile, this author — hitherto in the RVM camp — is learning the workings of rbenv. However, it should be said that both Wayne Seguin (RVM) and Sam Stephenson (rbenv) have built stellar tools that make project setup less about “getting up and running” and “it works on my machine” than ever before.