Ruby on Windows: pik to run code with a specific Ruby version

Ruby has an important release every year on Christmas Day. As a result, it’s very likely that over a period of time, you will have a few important versions of Ruby installed on your computer. Every time you install a new version with big changes, you invariably end up with the need to run an old program with an older version because of a dependency or deprecation (or just caution, in some cases).

On Linux or MacOS, you might use rvm or rbenv for managing multiple Ruby installations. On Windows, you have pik. In this post, we look at how pik is set up and used, and how you can integrate a call to pik torun your code with the correct Ruby version on the same computer.

Installing pik when using multiple Ruby Installations

pik is a gem that allows you to switch between different Ruby installations on a Windows computer. Although it is no longer maintained according to the github page, I found that it still works fine for me. It also works with JRuby (not just Ruby) by updating the PATH and other variables.

Open a command prompt that has Ruby 3.0 on the path and do gem install pik

$ gem install pik
Fetching pik-0.2.8.gem

----------------------------------------------------------------------------

*  If you're upgrading from a version <= 0.1.1, you'll want to delete the pik.bat file
   from all of your ruby versions. Gem uninstall should do the trick.

*  Install pik to a location that's in your path, but someplace other than your ruby\bin dir
   If you're upgrading from a more recent version, pik_install will overwrite the older files as needed.

    >path
      PATH=C:\tools\;C:\ruby\186-p368-mingw32\bin;C:\WINDOWS\system32;C:\WINDOWS

    >pik_install C:\tools

*  If this is a first-time install, add all the versions of ruby that you want to use with pik

    >pik add
    Adding:  186: ruby 1.8.6 (2009-03-31 patchlevel 368) [i386-mingw32]
     Located at:  c:/ruby/186-p368-mingw32/bin

    >pik add C:\ruby\IronRuby-091\bin
    Adding:  091: IronRuby 0.9.1.0 on .NET 2.0.0.0
     Located at:  C:/ruby/IronRuby-091/bin

    >pik add C:\ruby\jruby-1.4.0RC1\bin
    Adding:  140: jruby 1.4.0RC1 (ruby 1.8.7 patchlevel 174) (2009-09-30 80c263b) (Java HotSpot(TM) Client VM 1.6.0_14) [x86-java]
     Located at:  C:/ruby/jruby-1.4.0RC1/bin


----------------------------------------------------------------------------

Successfully installed pik-0.2.8
Parsing documentation for pik-0.2.8
Installing ri documentation for pik-0.2.8
Done installing documentation for pik after 3 seconds
1 gem installed

The first time you ever use pik on a computer, you will need to install it to a folder that is on your PATH other than the bin folder of any Ruby installation. Two common options are to install it to c:\windows\System32 (you will need to use an adminstrator command prompt for that) or to create a folder such as c:\tools for dropping executables of this kind and adding that folder to your system path. If you need help with any of these steps, just ask below and I will add the information here. Whichever folder you choose, do as shown below (but replace ‘c:\tools’ with the actual directory)

>pik_install C:\tools

Next, you add the current Ruby that is on the path by doing pik add as below.

$ pik add
** Adding:  300: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]
 Located at:  C:\Ruby30-x64\bin

Alternatively, you can add by using the full path to the Ruby installation bin folder as shown below.

$ pik add C:\Ruby30-x64\bin

Finally, to see all the Ruby installations that you have, just do pik list and you should get a list of Ruby versions that you have added. My list is shown below.

$ pik list
  187: ruby 1.8.7 (2013-06-27 patchlevel 374) [i386-mingw32]
  193: ruby 1.9.3p551 (2014-11-13) [i386-mingw32]
  224: ruby 2.2.4p230 (2015-12-16 revision 53155) [x64-mingw32]
  266: ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]
* 300: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]
  921: jruby 9.2.13.0 (2.5.7) 2020-08-03 9a89c94bcc OpenJDK 64-Bit Server VM 25.265-b01 on 1.8.0_265-b01 +jit [mswi...

Switching Versions on the command line

Once pik is set up, you can switch between versions by doing something like pik 266 or pik 300 and so on.

Here’s a session running a few of the commands:

d:\>ruby -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]

d:\>pik list
  187: ruby 1.8.7 (2013-06-27 patchlevel 374) [i386-mingw32]
  193: ruby 1.9.3p551 (2014-11-13) [i386-mingw32]
  224: ruby 2.2.4p230 (2015-12-16 revision 53155) [x64-mingw32]
  266: ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]
* 300: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x64-mingw32]
  921: jruby 9.2.13.0 (2.5.7) 2020-08-03 9a89c94bcc OpenJDK 64-Bit Server VM 25.265-b01 on 1.8.0_265-b01 +jit [mswi...

d:\>pik 224

d:\>ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [x64-mingw32]

d:\>pik 266

d:\>ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x64-mingw32]

d:\>pik 921

d:\>ruby -v
'ruby' is not recognized as an internal or external command,
operable program or batch file.

d:\>jruby -v
jruby 9.2.13.0 (2.5.7) 2020-08-03 9a89c94bcc OpenJDK 64-Bit Server VM 25.265-b01 on 1.8.0_265-b01 +jit [mswin32-x86_64]

Few things to note here:

  • pik list will show you the list of Ruby installations that it is aware of. The 3 digit code at the start of the line is the way to refer to that specific installation (e.g. 187, 193, 224, etc.)
  • When you do pik xxx, you can see that pik sets the correct path so that ruby -v points to the correct place
  • When picking a JRuby version, note that there is no Ruby on the path any more and you need to do jruby instead

Running a command file with the correct Ruby

This should be obvious but there is a minor catch. While running in the console, you simply do:

D:\>pik 266

D:\>ruby my_program.rb

You would expect that you could do the same in a command script but because pik itself is a batch file, the Windows Command stops running code at the end of it and does not run the next lines in the command.

For this reason, your CMD file needs to look like this:

call pik 266
ruby my_program.rb

Using CALL in a command file to run another command file executes the file and comes back to the current command file. Then, it continues running the rest of the code.

Notes and Warnings

A few minor things to be aware of:

  • Whenever you install a new Ruby, you should confirm that the 3-digit codes you are using are still correct. If it changes, there is a chance that the program will not run correctly.
  • If the code does not exist or is ambiguous, pik will wait for an input. Take care of that, especially if you intend to put pik into a scheduled job
  • If you use pik in a command file that is run from a scheduler, there is a possibility that the PATH is not set and pik may not be found. You might want to put the full path to the pik command (where you installed it) in that case.
  • Naturally, do not uninstall a Ruby that you are using in this way!

Links and References

If you are setting up Ruby on Windows, take a look at Installing Ruby 3.0 on Windows and Installing JRuby on Windows both on this site.

Other links and references:

  • Pik on GitHub: https://github.com/vertiginous/pik
  • Ruby website: https://rubyinstaller.org
comments powered by Disqus