5. Specifying Versions
The concept of a version is central to the RubyGems packaging scheme. Every gem package is assigned a version string consisting of digits and periods (e.g. “
gem command line program and the
gem Ruby command both take version constraint arguments. These arguments restrict the range of versions that are acceptable to the commands.
For example, if you want in install verion 0.4.14 of the
rake gem, you can say:
gem install --remote rake --version "0.4.14"
If you don’t care about the exact version of
rake, but want to make sure you get something later than version 0.4.10, you can say:
gem install --remote rake --version "> 0.4.10"
In fact, any of the standard comparison operators can be used for the version constraint.
Here are the available operators:
= Equals version != Not equal to version > Greater than version < Less than version >= Greater than or equal to <= Less than or equal to ~> Approximately greater than (see "Pessimistic Version Constraint" below)
Here are some examples:
gem 'mygem', "> 1.1" gem 'yourgem', "= 4.56.4"
If no version constraint operator is specified, RubyGems will assume that “=” was intended.
If your project is using the Rational Versioning Policy to assign version numbers, then your users can take advantage of that fact to carefully specify exactly what versions of your software should work with their system.
For example, suppose you have the following releases …
- Version 2.1.0 — Baseline
- Version 2.2.0 — Introduced some new (backward compatible) features.
- Version 2.2.1 — Removed some bugs
- Version 2.2.2 — Streamlined your code
- Version 2.3.0 — More new features (but still backwards compatible).
- Version 3.0.0 — Reworked the interface. Code written to verion 2.x might not work.
Your clients have validated that version 2.2.0 works with their software, but version 2.1.0 doesn’t have a feature they need). Their require line would look like this …
gem 'library', '>= 2.2.0'
This is called an OptimisticVersionConstraint. They are optimistic that the incompatible changes introduced in version 3.0 will still work with their software. They have no assurance of this (most likely verion 3.0 wasn’t written when they wrote the gem line). But they are willing to take the chance.
Some other clients of your library are not so hopeful. They fully expect that new interfaces will break their software, so they want to guard against accidently using the new interfaces. They use a PessimisticVersionConstraint that explicitly excludes your version 3.0.
gem 'library', '>= 2.2.0', '< 3.0'
Doing this is cumbersome, so RubyGems provides a pessimistic operator ~> (read: approximately greater than). Using the pessimistic operator, we get:
gem 'library', '~> 2.2'
Notice that we only include 2 digits of the version. The operator will drop the final digit of a version, then increment the remaining final digit to get the upper limit version number. Therefore ‘~> 2.2’ is equivalent to: [‘>= 2.2’, ‘< 3.0’]. Had we said ‘~> 2.2.0’, it would have been equivalent to: [‘>= 2.2.0’, ‘< 2.3.0’]. The last digit specifies the level of granularity of version control. (Remember, you can alway supply an explicit upper limit if the pessimistic operator is too limited for you).