Posts Tagged ‘rubinius’

Testing On Different Ruby Versions / Interpreters with rvm

Saturday, September 19th, 2009

I’ve been playing with a relatively new tool called rvm lately, and I’m loving it. rvm stands for Ruby Version Manager, and it does an exellent job at allowing different rubies to coexist. I currently have 7 versions installed on my machine:

ruby 1.8.6
ruby 1.8.7 patchlevel  72 (my system's default)
ruby 1.8.7 patchlevel 174
ruby 1.9.1
ruby 1.9.2 preview1
jruby 1.3.1
rubinius 0.11.0

rvm makes it ridiculously easy to manage them.

Installing

Let’s start by installing rvm

$ gem install rvm
$ rvm-install

and follow the instructions rvm-install gives you. Next, let’s install ruby1.9 (v1.9.1 by default).

$ rvm install 1.9

That’s it! rvm fetches the source, compiles the interpreter, and installs it in its own sandbox in ~/.rvm

For moar awesomes, you can install some non-MRI/YARV interpreters.

$ rvm install jruby
$ rvm install rubinius

Switching between versions

$ rvm use 1.9
$ ruby -v
ruby 1.9.1p243 (2009-07-16 revision 24175) [i686-linux]
$ which ruby
/home/mynyml/.rvm/ruby-1.9.1-p243/bin/ruby
$ rvm use system  #revert to using your system's ruby
$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
$ which ruby
/usr/bin/ruby

This speaks for itself, I believe.

Gems

Because each new version lives in its own sandbox, it starts off almost gemless (rvm pre-installs RubyGems and rake). You can install gems just as you normally would.

$ rvm use 1.9
$ gem install mynyml-every  #don't use sudo
$ rvm gemdir
/home/mynyml/.rvm/gems/ruby/1.9.1
$ gem list

*** LOCAL GEMS ***

mynyml-every (1.0)
rake (0.8.7)

Cross Version Testing

Here’s a rake task that will allow you to run your app’s tests across multiple ruby versions (provided you defined your own test task separately)

namespace(:test) do
  desc "Run tests on multiple ruby versions"
  task(:portability) do
    versions = %w( 1.8.6  1.8.7  1.9  jruby  rubinius )
    versions.each do |version|
      system <<-BASH
        bash -c 'source ~/.rvm/scripts/rvm;
                 rvm use #{version};
                 echo "-------- `ruby -v` ---------\n";
                 rake -s test'
      BASH
    end
  end
end

And run with:

$ rake -s test:portability

The reason the task looks hackish is because rvm isn’t a script, but a bash function. This function is loaded automatically when you open up a new shell because of the source line rvm-install added to your .bashrc file, but .bashrc itself isn’t loaded when you use #system. So the rake task first sources that function, and then runs everything else within the same session so that it uses its environment.

[update] As Wayne pointed out in the comments, there is a new rvm idiom that can be used to achieve this:

rvm 1.8.6,1.8.7,1.9,jruby,rubinius rake -s test

The rvm docs have also been updated to include this info.

Links

rvm’s official website has pretty good docs. You can also get a fairly good summary of functionality with

$ rvm help

source: http://github.com/wayneeseguin/rvm/
site/docs: http://rvm.beginrescueend.com/
tracker: https://www.pivotaltracker.com/projects/26822
group: http://groups.google.com/group/rubyversionmanager/