Software tools have different versions over the time, and this is the natural consequence of the evolution of the software. Each time some bug is solved, a new feature is developed or a new fancy thing is created inside that library, the creators or maintainers release that new version. These new versions can break old versions, for that reason we encounter different tags like this: 5.2.1 or 3.1.0. In a previous blog post we talked about this:
1- Installers
Here is the moment when we have to clarify concepts about certain terms and split the synonyms. In theory a package manager is quite different to an installer but developers often mix both concepts, they’re used as synonyms but it actually means different things
The installer is a program that can help us to install different versions of a program for the operating system. When we refer to an operating system we’re talking about the global environment of the system, for instance: Linux, MacOs or Windows. So, this means that the installer basically installs software globally in our operating system. But there are other critical difference:
- An installer, generally speaking, makes no effort to coordinate it’s installs with what is already installed in the machine, so it can get conflicts easily with other programs without you noticing it until you try to run the other program. So, it's better to use the installers carefully because it can break programs from your machine
Note: Is fair enough to say that Windows tends to use installers more frequently than the other operative systems
Another key difference with installers is that you may get critical updates for the operating system itself automatically, but a lot of the software installed will require manual intervention to update. And finally, if you want to uninstall the library it is easy to do it.
2- Package Managers
Meanwhile, when we talk about package managers we refer to the versions of a given software that depend on other software (also called dependencies), not the operating system. This means that a package manager “does” coordinate installs, to prevent package conflicts, as a result of which some installs will fail, in order to prevent a package conflict that would disables the present install or an earlier one
Let’s make a simple example:
- - One thing is to install Ruby 2.3.1 on Linux, MacOS or Windows (using an Installer and doing it globally)
- - Another thing is to install Ruby On Rails 5.2.1 via the “gem install” command (using a Package Manager to work on a given project).
- In this example the package manager that we call with the command “gem install” will take care about the coordination of the versions of the packages, while the ruby installation via the Installer, will install Ruby it doesn't matter what.
Installer
Package Manager
3- Dependency Managers
Until now we were talking about compatibility or incompatibility between an isolated tool, like Ruby. However, almost always these tools need to interact with other tools or software and they need to take care about the version we’re connecting to. This is a simple example
You use Rails 5.2.1 as a web development framework. You decide to use a gem (library that does something specifically) like Devise that simplifies the authentication process for the users. So you try to use the devise version 1.0.2. As you can see we’re now dealing with two quite different tools where each one of them has a different version. Thats a big problem to solve, because the devise gem needs to match with the Rails version
Matching different tools with different versions
The key word here is “Matching”. Matching different tools with the right versions is a big issue to solve, but is something that can be done with another tool called Dependency Manager. In Ruby we have Bundler. Bundler is the tool for excellence in the Ruby environment to deal with compatibility between different gems. Remember that a gem is a package.
A package is a set of code that helps us to achieve a particular task: like authenticating users or helping us with the Search Engine Optimization (SEO) inside the web project, for instance. With bundler if we have some incompatibilities they will let us know for sure, because it raises and error almost immediately. But if the different versions match, bundler will get the right versions for us.
Let’s see this examples
Here we can see how devise 1.0.2 is not compatible with Rails 5.2.1. If we have 2 or more packages that aren’t compatible between them we’ll see that error prompted almost immediately. Let’s check next example
Here we have the 3 packages compatible by versions. Devise 4.6.0 is compatible with Rails 5.2.1.
Now you can imagine how hard it could be to manage all of this manually. Fortunately we have Bundler that can help us achieve this goal. Later we’ll be touching bundler deeply.
I think this is enough for now about versions and releases. Our main concern now is to play with Ruby and to have the basics about the language. See you on the next blog post
Thanks for reading
Daniel M