Dr Nic

Future proofing your Ruby code. Ruby 1.9.1 is coming.

Bugger.

I’m a Ruby monogamist. I use the Ruby that comes with Leopard (ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0]). Oh sure I’ve cheated on my Ruby a couple of times. It was just sex, I didn’t fall in love, I promise.

My machine has had various versions of jRuby, Rubinius and MacRuby installed at various times, but I don’t think it’s ever had two working copies of Ruby MRI (Matz Ruby Implementation) at a time.

Ok, that’s a lie. On Christmas Day 2007, Matz released Ruby 1.9. Yes I was a deviant. I installed it. But I didn’t inhale. ruby19 sat on my filesystem outside the $PATH. It was a trophy not a tool.

My Ruby monogamy was working out perfectly for me, whilst I collected futurist and novelty Ruby implementations as a passive hobby, until yesterday when I saw the above tweet.

That’s a bit of a bugger. I mean, why was he playing with Ruby 1.9.1 anyway?

Or perhaps having multiple version of Ruby on one computer isn’t some illicit activity. Everyone else is doing it, Your Honour.

I still didn’t care for having multiple ruby versions lying around in my path; but I had to fix rubigen. I just wanted a way to fix bugs against ruby 1.9+ and move on with my life. I didn’t want to have to do any manual work in order to set this up. Surely someone else has solved this problem already?

MultiRuby

Yes. Ryan Davis did solve this problem already. You can follow his instructions and get most of the answers I needed. Except as of today, multiruby wasn’t pulling down my nemesis ruby 1.9.1 prerelease versions, just the latest 1.9.0 version. (update: 1.9.1 is out; installation instructions below are updated)

Also, I couldn’t figure out how to setup rubygems and I couldn’t figure out how install all the fun gems that my code needed. Ryan fixed me up with this answer too.

MultiRuby is really nice in that it installs all the version of ruby into a safe place (~/.multiruby/) and has nice ways to add and remove versions of ruby that you want to test against. To run the tests for rubigen I ran the following code. It takes about 30 minutes from scratch.

sudo gem install ZenTest
multiruby -e "p 1+1"
multiruby_setup mri:svn:tag:v1_8_6_114
multiruby_setup mri:svn:tag:v1_9_1_0

multiruby_setup update:rubygems
multiruby -S gem install --no-ri --no-rdoc --development test-unit rspec mocha rails

To get the full list of available ruby tagged releases, ask the SVN repo:

svn list http://svn.ruby-lang.org/repos/ruby/tags

Sometimes I got time out errors on the gem installs

ERROR:  While executing gem ... (Gem::RemoteFetcher::FetchError)
    timed out (http://gems.rubyforge.org/gems/rails-2.2.2.gem)

The next section helps fix this if it occurs for you.

Sake tasks to help with multiruby

Whilst multiruby_setup comes with some useful helpers, and hoe generates a helpful ‘rake multi’ runner for test/unit tests of hoe gems, I wanted more helpers. These have been compiled as sake tasks in http://github.com/drnic/sake-tasks.

To install them from scratch (initial blog post):

sudo gem install sake
cd /tmp
git clone git://github.com/drnic/sake-tasks.git
cd sake-tasks
rake install:all

You can toss away the repo after installing the sake tasks.

Installing gems into multiruby

Each version of ruby has its own rubygems cache. To install a gem into each ruby version:

sake multiruby:gems:install GEM=gemname
sake multiruby:gems:install GEMS=gem1,gem2

Want to see what gems were installed for each version of ruby?

multiruby -S gem list

Running tests

If you use hoe, and your tests are traditional test/unit tests, then hoe comes with a very helpful rake multi task.

For everyone else, use the following sake tasks:

sake multiruby       # Runs any tests or specs in current project against multiruby
sake multiruby:spec  # Runs specs in current project against multiruby
sake multiruby:test  # Runs tests in current project against multiruby

Miscellaneous MultiRuby management

When I was fixing rubigen, I had some failing tests against 1.9.0-5 but not against 1.9.1, so I decided I hated 1.9.0 and stopped running tests against it. You can stop supporting a version of ruby with:

multiruby_setup rm:1.9.0-5

Not sure what versions of ruby you’re supporting?

multiruby_setup list

Cucumber

Theoretically you could try something like (after installing cucumber gem into multiruby):

multiruby -S cucumber features
multiruby -S cucumber --format progress features

My scenarios are failing at the moment. All of them. And the log/stdout files are overwriting each other in the tmp folder. To isolate it down to one scenario you’d try something like:

multiruby -S cucumber features/executable_generator.feature:7

You can now easily isolate and run a specific cucumber scenario against a specific ruby version by copy+pasting from the output of the above line. For example:

~/.multiruby/install/v1_8_6_114/bin/ruby -S cucumber features/executable_generator.feature:7

Perhaps this is too much information. I’m still getting cucumber + multiruby working together, so I’ll add new ideas to the bottom of this post as I figure them out.

Running rake tasks

I’ve been poking around a bunch of other people’s gems seeing how many gems current pass against ruby 1.9.1 (answer: not many). When I came across nokogiri, I found that I needed to trigger the build steps of the C code first before running the tests. The simplest way to do this was via its own rake tasks.

multiruby -S rake clean test

Here we are calling the ‘clean’ task first, so that the C code is rebuilt from scratch for each new ruby version. BTW, there are 6 failing tests for v1_9_1_preview2.

Related posts:

  1. Validate and Save your Ruby in TextMate – with secret Rubinus superpowers In some TextMate bundles, if you save a file it...
  2. Hacking someone’s gem with github and gemcutter Ever used a rubygem, found a bug, and just...
  3. hash bang cucumber I don’t know if this is a good idea or...
  4. Cucumber: building a better World (object) How to write helper libraries for your Cucumber step definitions...
  5. newgem 1.0.0 all thanks to Cucumber The New Gem Generator (newgem) was exciting, moderately revolutionary, and...

31 Responses to “Future proofing your Ruby code. Ruby 1.9.1 is coming.”

  1. Christian says:

    Looks great. Now, maybe I too can get my code up to date :)

  2. Bob Aman says:

    Neat. I think I prefer the simplicity of just installing to sane paths and then using symlinks. Testing in each version ends up being pretty reasonable too.

    rake spec
    rake19 spec
    jruby -S rake spec

  3. [...] Future proofing your Ruby code. Ruby 1.9.1 is coming. – Advice from Dr. Nic. [...]

  4. [...] Dr. Nic escreveu um post bem legal sobre o multiruby e como [...]

  5. Rob Seaman says:

    Great information, I’m now using multiruby to manage my Ruby installations and switching between them with .bash_login aliases:

    # switch between ruby verisions
    export ORIGPATH=$PATH
    alias mr186p287=’export PATH=~/.multiruby/install/1.8.6-p287/bin:$ORIGPATH’
    alias mr187p72=’export PATH=~/.multiruby/install/1.8.7-p72/bin:$ORIGPATH’
    alias mr191pre2=’export PATH=~/.multiruby/install/1.9.1-preview2/bin:$ORIGPATH’
    alias mroff=’export PATH=$ORIGPATH’

  6. [...] a big round up of Ruby 1.9 news, links, and resources, but till then you might find Dr Nic’s guide “Future proofing your Ruby code – Ruby 1.9.1 is coming” to be very useful. Sam Ruby’s OSCON presentation on Ruby 1.9 should also prove illuminating if [...]

  7. Adam Salter says:

    Just a note that Rake supports “global” rakefiles… and has for a few months now. Ie No more need for sake.

    $ rake –help

    -g, –system Using system wide (global) rakefiles (usually ‘~/.rake/*.rake’).

    Just put your tasks into ~/.rake/*.rake and call with:
    rake -g my_special_task

  8. Dr Nic says:

    @Adam – oh that’s nice. So I can have my “sake-tasks” inside ~/.rake/sake-tasks (rename *.sake to *.rake), remove sake gem, and alias sake=”rake -g” :)

  9. Jim Gagne says:

    I keep getting compile errors while trying to compile 1.9.1.rc1. Here’s the error log. Any thoughts?

    Running command: nice make -j4 &> log.build
    /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:279:in `run’: ERROR: Command failed with exit code 512 (RuntimeError)
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:178:in `gnu_utils_build’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:83:in `build_and_install’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:80:in `chdir’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:80:in `build_and_install’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:61:in `each’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:61:in `build_and_install’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:60:in `chdir’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:60:in `build_and_install’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:53:in `chdir’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/lib/multiruby.rb:53:in `build_and_install’
    from /opt/local/lib/ruby/gems/1.8/gems/ZenTest-3.11.0/bin/multiruby_setup:68
    from /opt/local/bin/multiruby_setup:19:in `load’
    from /opt/local/bin/multiruby_setup:19

  10. Dr Nic says:

    @Jim, sorry can’t help. Worked for me. I did clean out ~/.multiruby beforehand as I was toying around with a few things. If that doesn’t work, try the ruby dev mailing list perhaps.

  11. [...] 1.8, e seu código precisa estar pronto para elas. Para ajudar, leia o gia do Dr Nic, “Future proofing your Ruby code – Ruby 1.9.1 is coming“, que é bem interessante. Veja também a apresentação do Sam Ruby na OSCON, onde as [...]

  12. [...] this message were removed to make it a legal post.] Dr. Nic wrote something about this recently. http://drnicwilliams.com/2008/12/11/…our-ruby-code/ Regards, [...]

  13. [...] wait for a new One Click Installer), check it out, test your code against it (Dr Nic has written a great guide about this), see which gems don’t work, and generally use it as a “stick in the sand” to measure a future [...]

  14. Dr Nic says:

    Article updated for 1.9.1 release instructions

  15. universa1 says:

    Since i had the problem of multiruby not building/installing anything under ubuntu i poked around in the code, and updated some small bits (basically removed “&” from the system calls) and updated the rubygems update spec, since it referenced a non-existent url.

    http://pastie.org/375339

  16. [...] Algumas bibliotecas e gems podem não funcionar corretamente. Teste seu código antes, e veja esse guia do Dr. Nic que alerta sobre algumas gems com problemas, além de dicas sobre o [...]

  17. Great article Nic!

    If someone is experiencing an error with the command
    multiruby_setup update:rubygems
    I strongly suggest to have a look at the following patch I submitted a couple of minutes ago.

    http://rubyforge.org/tracker/index.php?func=detail&aid=23806&group_id=419&atid=1680

  18. [...] wait for a new One Click Installer), check it out, test your code against it (Dr Nic has written a great guide about this), see which gems don’t work, and generally use it as a “stick in the sand” to [...]

  19. [...] Future proofing your Ruby code. Ruby 1.9.1 is coming. – Australian superhero Dr Nic Williams takes a look at using multiruby to run Ruby 1.9 and 1.8 on the same system. This is quite a different approach to just installing them separately with different suffixes and might suit your workflow better.. Ken Collins has also written MultiRuby The MacPorts Way which takes a slightly different approach. [...]

  20. [...] Preparando seu código para o futuro. Ruby 1.9 vem aí. – O super herói australiano Dr Nic Williams dá uma olhada em como rodar o Ruby 1.9 e 1.8 no mesmo sistema usando o multiruby. Essa é uma maneira um pouco diferente do que instalar as duas versões separadas com diferentes sufixos mas pode se adaptar melhor a sua rotina de trabalho. Ken Collins que também escreveu MultiRuby The MacPorts Way nos mostra uma maneira um pouco diferente. [...]

  21. [...] Future proofing your Ruby code. Ruby 1.9.1 is coming. – Australian superhero Dr Nic Williams takes a look at using multiruby to run Ruby 1.9 and 1.8 on the same system. This is quite a different approach to just installing them separately with different suffixes and might suit your workflow better.. Ken Collins has also written MultiRuby The MacPorts Way which takes a slightly different approach. [...]

  22. [...] Future proofing your Ruby code. Ruby 1.9.1 is coming [...]

  23. [...] esperar por um novo One Click Installer), experimente, teste seu código nele (Dr Nic escreveu um grande guia sobre isso), veja que gems não funcionam, e genericamente use isso como um auxilio para medir uma futura [...]

  24. Dr Nic says:

    Until multiruby is patched, it looks like it will always pick up 1_9_1_rc2 as the latest 1_9_1 version as it is alphabetically later than 1_9_1_0. The multiruby code will ignore /preview/ tags, but currently doesn’t ignore tags matching /rc/.

  25. [...] my boss I’m obliged to do the things he tells me to do. He told me to read his post about Future-proofing Your Ruby Code and in particular the instructions about installing [...]

  26. %-) genuinely interested by this website

  27. Gah, I really do not like autotest / multiruby, wish I had time to come up with an alternative

  28. [...] If you haven’t heard about multiruby yet, you should probably start reading this excellent post by Dr Nic. [...]

  29. Downloading ruby 1.9.1 and the updated instructions, I updated my code finally.
    Thanks a lot,

  30. [...] I hope this helps someone else. I decided that I need to get setup with Ruby 1.9, and I found this nice write up. [...]

  31. There is a better way to install multiple Rubys to play with: rvm

    http://rvm.beginrescueend.com/

    I don’t know about using it to run a production system, etc… but it works pretty well for testing and your own personal environment.