Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, some JS stuff and more...

Github:
/danielmoralesp
Twitter:
@danielmpbp

2024-07-09

Differences Between RVM, Rbenv and RubyInstaller

Differences Between RVM, Rbenv and RubyInstaller

In one of the latest blog posts I’ve been talking about the Differences Between Installers, Package Managers and Dependency Managers. I said that in modern software development it is almost impossible to create software without these kinds of tools because we have to take care about the different versions between different packages or libraries. 

At the beginning, we tend to be confused about these terms: Installes, Package managers and Dependency Managers, so for that reason I wrote that post and my suggestion is to read it before to continue and with that you can have the right context about the current blog post

Different ways to install Ruby

If you have Linux or MacOs you can install it automatically, directly and globally using any of these package managers: RVM or rbenv.

If you have a Windows system, you need to install any Ruby version manually, directly and globally to your operating system using an installer called RubyInstaller for Windows

Normally you’ll have different projects  that use different Ruby versions on your Operating System. For instance you have Project A with the Ruby version 2.7.5 which belongs to a new side project you started to work on weekends. And your company has been working on a Project B with Ruby 1.9.3 version (a legacy one), and they’ve never upgraded the project. How in the hell you’ll deal with the different ruby versions on your OS? Short answer: With the Package manager (Linux or Mac) or with the installer (Windows)

So let’s clarify some concepts:
  • - If you use a package manager like rvm or rbenv
  •   - with a few commands you can have different versions of Ruby in your OS. 
  •   - you can switch any time and easily from one Ruby version to another. Even if you have some different projects    - running on different versions
  • - If you use the Windows Installer
  •   - you have to install the different Ruby versions by yourself each time you need it
  •   - you need to make the switch manually between different versions

Package managers will make your life easier and happier :)

RVM vs Rbenv

It’s hard to say which one is most popular or better. What we can say is that both work almost in the same way, but they use different commands. Honestly I’ve seen more documents or tutorials of people who use rvm, but I think it is more a personal preference of each instructor. 

In some environments I found it easier and less buggy to work with rbenv than rvm, like in Windows. In Linux and MacOs I found better and smooth results with rvm. We’re going to use both here in 2 Operative Systems (Linux and Windows), so don't be shy to test both of them. 

1- RVM


Link: https://rvm.io/

Ruby Version Manager, often abbreviated as RVM, is a software platform for unix-like operating systems designed to manage multiple installations of Ruby on the same device.

The entire ruby environment including the Ruby interpreter, installed RubyGems, and documentation is partitioned. A developer can then switch between the different versions to work on several projects with different version requirements. In addition to MRI (Matz’s Ruby Interpreter), the standard Ruby interpreter, RVM functions as an installer for various other implementations of Ruby. These include JRuby, mruby, MacRuby, IronRuby, Maglev, Rubinius, Ruby Enterprise Edition, Topaz, and GoRuby (an interpreter optimized for code golf). In addition, RVM supports the installation of patched versions of MRI.

For a start, not only does RVM make installing multiple ruby interpreters / runtimes easy and consistent, it provides features such as gemsets that aren't typically supported out of the box on most ruby installs.

RVM also lets you use different rubies in a manner that won't mess with your existing ruby install (unless you tell it to) as well as letting you run multiple different rubies in separate terminals concurrently!

Gem sets
RVM gives you compartmentalized independent ruby setups. This means that ruby, gems and irb are all separate and self-contained - from the system, and from each other.

You may even have separate named gemsets.

Let's say, for example, that you are testing two versions of a gem, with ruby 2.1.1. You can install one to the default 2.1.1, then create a named gemset for the other version, and switch between them easily.

Example: testing gems
$ rvm 2.1.1@testing

will use a '2.1.1@testing' GEM_HOME (be sure to create it first), whereas:

$ rvm 2.1.1

will use the default 2.1.1 GEM_HOME

Example: Rails versions & upgrading apps
To illustrate the point, let's talk about a common use case. Assume you are testing out a rails application against a new Rails release. RVM makes such testing very easy, by letting you quickly switch between multiple Rails versions. First, let's set up the environments:

$ rvm 2.1.1
$ gem install rails -v 4.1.0

$ rvm gemset create rails410 rails320
Gemset 'rails410' created.
Gemset 'rails320' created.

$ rvm 2.1.1@rails410
$ gem install rails -v 4.1.0

$ rvm 2.1.1@rails320
$ gem install rails -v 3.2.0
Note that, for each of the ruby installs above, you can have completely separate versions!

Now that your environments are set up, you can simply switch between Rails versions and Ruby versions as follows.

$ rvm 2.1.1@rails410 ; rails --version

Rails 4.1.0

$ rvm 2.1.1@rails320 ; rails --version

Rails 3.2.0
If you are deploying to a server, or you do not want to wait around for rdoc and ri to install for each gem, you can disable them for gem installs and updates. Just add the following line to your ~/.gemrc or /etc/gemrc:

gem: --no-rdoc --no-ri


2- Rbenv

Link: http://rbenv.org/

Compared to RVM, rbenv does not manage gemsets nor install different Ruby versions. It only manages different ruby versions. Tasks like installing different gemsets are now better off handled by other tools such as Bundler which is a much better tool for handling dependencies in gems, and many gems these days are already using it. 

Both rbenv and RVM are Ruby version management tools. RVM is more resourceful but rbenv is lightweight which makes it a strong contender for RVM. RVM is used to manage and install different versions of Ruby and gemsets on systems where Rbenv is a lightweight Ruby version management tool.
rbenv does…
  • - Provide support for specifying application-specific Ruby versions.
  • - Let you change the global Ruby version on a per-user basis.
  • - Allow you to override the Ruby version with an environment variable.

In contrast with RVM, rbenv does not…
  • - Need to be loaded into your shell. Instead, rbenv's shim approach works by adding a directory to your $PATH.
  • - Override shell commands like cd or require prompt hacks. That's dangerous and error-prone.
  • - Have a configuration file. There's nothing to configure except which version of Ruby you want to use.
  • - Install Ruby. You can build and install Ruby yourself, or use ruby-build to automate the process.
  • - Manage gemsets. Bundler is a better way to manage application dependencies. If you have projects that are not yet using Bundler you can install the rbenv-gemset plugin.
  • - Require changes to Ruby libraries for compatibility. The simplicity of rbenv means as long as it's in your $PATH, nothing else needs to know about it.

How does it work?
At a high level, rbenv intercepts Ruby commands using shim executables injected into your PATH, determines which Ruby version has been specified by your application, and passes your commands along to the correct Ruby installation.


3- RubyInstaller for Windows

Link: https://rubyinstaller.org/

We have to say that you can install ruby directly without using RVM or Rbenv, but remember that these package managers help us to deal with different versions of Ruby according to the project we’re working on. As we learnt RVM is a unix-based package, that means that we cannot use it directly on Windows. Something similar happens with Rbenv.

Ruby’s difficulties on Windows stem from the fact that it’s very different, under the covers, from both Linux and macOS. Those two operating systems have similar “toolchains” because both are based on Unix. This means that they can use the same compiler, shared library system, and other tools to build the Ruby interpreter and Ruby libraries, which are called “RubyGems.” or Gem Sets as we learned with RVM

Ruby is an open-source language written by volunteers. It was developed on Unix-based computers, so making the language work there came first. There’s always been an effort to make it work on Windows as well, but the Unix-like environments got priority.

For many years, trying to develop Ruby code on a Windows computer meant dealing with issues that someone using a Mac or Linux computer wouldn’t face. To a certain extent, that’s still true. When seeking help for a problem you run into, you’ll likely find fewer search results for Windows. Plus, you may find that less common libraries don’t even offer a Windows version.

And if you’re planning on deploying your code, you should think about what that platform will be. For example, if you want to write a Ruby on Rails web application, you’ll likely be deploying it onto a Linux web server. It’s always best to keep the development environment as close as possible to the production environment so that you don’t get any surprises when your code goes live.

One of the most surprising and pleasant developments in the software world in recent years has been Microsoft warming up to open source. They’ve also embraced open source by bringing Linux to Windows!

That’s right, Windows 10 allows you to install a Linux “subsystem” on the same computer. This means you can install and run Linux applications. This also means that you can use Linux package managers to install the traditional Ruby environment. It’s called the Windows Subsystem for Linux (WSL), but we’re not going to covered here, we’re going to use Windows itself given the fact that we’ll be running a Windows instance in AWS to demonstrate how to install ruby right there

However, if you have a computer running an older version of Windows,  (WSL) isn’t available to you. But fear not. There’s still active development on Ruby for Windows, including right up to the most recent version of Ruby. This project is called RubyInstaller, and it works its magic by using the MSYS2 system for providing Unix-like libraries on Windows as well as MinGW (Minimal Gnu for Windows), which is a large library of Unix-like packages that work on Windows

RubyInstaller is the easiest and most widely-used Ruby environment on Windows. RubyInstaller combines the possibilities of native Windows programs with the rich UNIX toolset of MSYS2 and the large repository of MINGW libraries. RubyInstaller is a great way to use Ruby for development and production, especially if you just want to use Ruby for day-to-day scripting or require access to Windows resources such as hardware devices, DLLs, OLE, graphical user interfaces or the GPU.

Although the Ruby community is continuously working to make the experience of using Ruby on Windows as smooth as possible, it’s still slower and less convenient compared to Linux or MacOS. Some of the shortcomings are due to certain Windows operating system internals (such as its poor shell support), and others are due to the fact that so many Ruby developers simply prefer a UNIX-style system.

Ubuntu Linux or MacOS are great as Ruby development platforms. They provide the best overall Ruby experience. If you use Ruby for a larger project you might consider moving to one of those operating systems. Ruby is strong at cross-platform development, so it’s easy to use Ruby on Linux for development and RubyInstaller on Windows in production or vice versa.

Windows Subsystem for Linux provides a Linux environment on top of Windows. Most of the development tools available for Linux can be used directly in WSL. It is well-suited for web development with Rails, and it provides network and filesystem access, but access to hardware devices and interoperability with native Windows software both are very limited. Ruby can be installed as a package from the selected Linux distribution (typically Ubuntu) or through rvm or some similar Ruby version manager. WSL is not suitable for production use.

Cygwin is another alternative to RubyInstaller. It provides a POSIX environment on Windows. Ruby can be installed along with many other tools, but Cygwin cannot directly execute arbitrary Linux binaries (in contrast to WSL). Cygwin offers only a few advantages over RubyInstaller such as a better shell and universal UTF-8 support. But it is slower, and makes accessing Windows’ native resources more difficult.


Conclusions
I think that the first decision you have to make is if you’re going to work on a Unix-based system or a Windows System. With that decision you can move forward. We suggest to use a Unix-based system to work with Ruby, but if you have no choice, you can decide for WSL. But if you have to use native Windows components is better to use the RubyInstaller for Windows