Upgrade Ruby from 2.7 to 3.0
Ruby 3.0 was released on December 25th 2020. We can now enjoy the great new features of this version, such as performance boost (we talked about that in this recent article ), ractors for concurrency, fiber schedulers, and type checking.
If you already have an application running in production and want to be able to use such benefits you’ll need to upgrade your Ruby version.
This article will cover the most important aspects that you’ll need to know to get your Ruby application from version 2.7 to 3.0
- 1. Preparations
- 2. Gems compatibilities and deprecations
- 3. Default Gems
- 4. Language Changes
- 5. Upgrade and Tests
- 6. Wrapping up
1. Preparations
Before beginning with the upgrade process, we have some recommended preparations:
- For this article we assume that your app is running in the latest patch version of Ruby 2.7.
- We advise you to have at least 80% of test coverage unless you have a dedicated QA team.
- Follow a workflow to actively manage at least two environments: staging and production.
2. Gems compatibilities and deprecations
Make sure you check the documentation of the gems that you’re using to find out if they are compatible with Ruby 3.0 and update your dependencies with the gem’s compatible release.
If you’re running on 2.7 you may have seen deprecation warnings coming from the gems. If so, it’s likely that the gem maintainers have already addressed these deprecations in a newer version to comply with Ruby 3. Make sure you update the gems to the version where the deprecation is fixed.
3. Default Gems
Also, in Ruby 3 there are a lot of gems that were added or removed to the standard library. You can check the list here .
For example, the webrick
gem was removed from the default gems due to vulnerability issues , so if you use Webrick, you need to add the gem explicitly.
On the other hand, gems like digest
, base64
and time
are now added by default to Ruby, so if you have them in your Gemfile you’ll need to remove the references.
4. Language Changes
Code that raised deprecation warnings in Ruby 2.7 will now result in ArgumentError or different behavior, such as:
- Change : Positional arguments and keyword arguments will be separated now.
# Before:
def foo(*args, &block)
target(*args, &block)
end
# Now: You need to explicitly delegate keyword arguments.
def foo(*args, **kwargs, &block)
target(*args, **kwargs, &block)
end
- Change : Procs accepting a single rest argument and keyword arguments are no longer subject to autosplatting.
# Before:
pr = proc{|*a, **kw| [a, kw]}
pr.call([1]) # [[1], {}]
pr.call([1, {a: 1}]) # [[1], {:a=>1}]
# Now: You need to explicitly delegate keyword arguments.
pr = proc{|*a, **kw| [a, kw]}
pr.call([1]) # [[[1]], {}]
pr.call([1, {a: 1}]) # [[[1, {:a=>1}]], {}]
- Arguments forwarding (…) now supports leading arguments
def method_missing(meth, ...)
send(:"do_#{meth}", ...)
end
- Change : Endless method definition is added.
def square(x) = x * x
There are other language changes that we didn’t highlighted here. You can see the full list of them in the Rails 3.0 News .
5. Upgrade and Tests
After adjusting your code to get ride of all deprecation errors and learn everything that will work differently in the language, it’s time to add the ruby 3.0 in your Gemfile
and run your tests. You’ll likely have a bunch of things to fix in your test suite also, so make sure that everything works like a charm.
It’s now time to deploy your changes to the staging environment and make sure it passes all QA tests.
6. Wrapping Up
If you successfully followed all of these steps, you should now be running Ruby 3.0 in your application and can now enjoy everything that this new version has to offer.
Do you have any other useful tips or recommendations? Did we miss anything important? We would love to add it to this article.
Need to upgrade your Ruby or Ruby on Rails versions but your team just doesn’t have the time? Let our team of experts at FastRuby.io upgrade your application. Get in touch!