Friday, September 6, 2013

RVM oddity

Even though I don't use all the features, I love RVM... it generally makes my life easier when dealing with new/multiple versions of Ruby and/or different gemsets. Definitely recommended, although I know there are people who swear by rbenv. In either case, they both make magical things happen by working in the background... all terrific as long as it works. But when it doesn't work as expected, it can really be difficult to diagnose and resolve.

Case in point. The project I'm working on is done in Ruby 1.9.3-p327 and I have a 'Rails3213' gemset that I've been using. I've always used a .rvmrc file (analogous to .vimrc or .bashrc) to specify my desired ruby and gemset versions on a per-project basis. Somewhere along the line, I upgraded RVM and then get a prompt that I should switch from .rvmrc to .ruby-version for my ruby/gemset information, which I followed.

Mistake. Unbeknownst to me, the information in my .ruby-version file was silently ignored and I was using gems from another location inside RVM.  It only came to light when I encountered some strange test results and then debugging changes I made to a gem seemed to disappear. I finally got a clue of what was going on through a tell-tale signal from vim's "tag jump" (Ctrl-]) command : I had been working on the gem in:
~/.rvm/gems/ruby-1.9.3-p327@rails3213/clearance-1.0.1
but when Ctrl-] I jumped to a method definition inside vim, I was routed to a file in:
~/.rvm/gems/ruby-1.9.3-p327/clearance-1.0.1
Going back to the RVM site, I saw that .rvmrc was still (probably always had been?) the preferred way to define things, so good-bye .ruby-version, hello .rvmc, and things were back to normal.

Lesson Learned. For the future, if I run into such strangeness again, I'll look to my environment much earlier to make sure I'm working with the right set of gems or rubies or whatever.  One thing I was reminded of that I had forgetten was that rvm nicely tells you the ruby & gemset that you're using when you enter a project directory with a .rvmrc file:
Using /home/jseidel/.rvm/gems/ruby-1.9.3-p327 with gemset rails3213
And if I need to check up on things, a quick :
rvm list && rvm gemset list
tells me all I need to know that I'm in the right place:
rvm rubies
   ruby-1.9.2-p290 [ x86_64 ]
=* ruby-1.9.3-p327 [ x86_64 ]
   ruby-1.9.3-p448 [ x86_64 ]
   ruby-2.0.0-p0 [ x86_64 ]
   ruby-2.0.0-p247 [ x86_64 ]

# => - current
# =* - current && default
#  * - default
gemsets for ruby-1.9.3-p327 (found in /home/jseidel/.rvm/gems/ruby-1.9.3-p327)
   (default)
   global
   rails3020
   rails3212
=> rails3213
Another thing I'm going to do more carefully is re-create my tags file whenever there are gem changes so that I'm always up-to-date. I found a great bash one-liner (if I can remember where I found this, I'll come back and give credit):
ctags -R . $(bundle show --path)
This puts all your gems into the tags file which means that you can Ctrl-] on methods that are included in Rails or other gems.

Update:
Now when I enter the project directory, I get the RVM warning:
You are using '.rvmrc', it requires trusting, it is slower and it is not compatible with other ruby managers,
you can switch to '.ruby-version' using 'rvm rvmrc to [.]ruby-version'
or ignore this warnings with 'rvm rvmrc warning ignore /home/jseidel/Dev/MyPasswords_Upgrade/.rvmrc',
'.rvmrc' will continue to be the default project file in RVM 1 and RVM 2,
to ignore the warning for all files run 'rvm rvmrc warning ignore all.rvmrcs'.
It may be slower (I sure can't tell the difference), but I'm going to stick with .rvmrc as long as I can.