The changes I missed in the latest versions of Ruby

Mathieu Fosse
Stuart Tech
Published in
6 min readJan 25, 2018

As a developer it’s important to keep track of the changes made on your favorite programming language. It’s easy to say, but in fact I tend to pay more attention to third party library updates that I use in my projects (new features, vulnerabilities) than the updates of my programming language. That’s why I try on a regular basis to step back and review what changed in my favorite programming language: Ruby.

As you may know, every Christmas the Ruby core team releases a new version of Ruby. I took advantage of it to dig into the Ruby documentation and the Ruby bug tracker to see what I missed in the latest version of Ruby.

I thought it would be nice to share what I found and shine a light on some of the features that I use on a daily basis and find useful.

I also take advantage of it to present some of the cool new features coming in version 2.5 which was released last month (look at the 🆕).

Language features

Let’s start with the language itself. Usually these kind of changes help you to write less and more robust code. That’s why you should take care of them.

Safe navigator operator

You most likely already know the try method from ActiveSupport. Ruby implemented this same behaviour with the & operator.

General Delimited Input

General Delimited Input are super useful to write concise code. It starts with a % and it is followed by a letter which indicates the builder being used and then its arguments are surrounded by a Ruby operator.

For example to build an array of string any of the following will work the same:

%w{hello}
%w[hello]
%w=hello=
%w+hello+
%w-hello-
%w/hello/
%w:hello:
%w$hello$
%w%hello%
%w#hello#
%w>hello>
%w;hello;
%w.hello.
%w,hello,
%w@hello@
%w!hello!
%w^hello^
%w&hello&
%w~hello~

And here is a list of useful builder operator I like to use:

🆕 Rescue, else, ensure in any block

Ruby 2.5 makes ruby code more cleaner and easy to read by allowing developers to use directly rescue, else, ensure keywords in any do…end block.

String management

One thing for sure I use on a regular basis is string transformation.

🆕 String#start_with?

Even if Ruby follows the principle of least surprise, you could be surprised that the String#start_with? didn’t accept a regexp as argument. With Ruby 2.5 it’s finally possible:

http://ruby-doc.org/core-2.5.0/String.html#method-i-start_with-3F

🆕 String#delete_prefix and String#delete_suffix

New methods to easily delete either a prefix or a suffix from a string.

http://ruby-doc.org/core-2.5.0/String.html#method-i-delete_prefix

Regexp#named_captures

There’s something I’ve learnt while being a developer: you are rarely a regexp expert. The syntax is hard to learn and read but regexp is super useful especially when you have to extract variables from a string to create a hash.

You can use “named_captures” for that since Ruby 2.4:

http://ruby-doc.org/core-2.5.0/MatchData.html#method-i-named_captures

Collection management

The Ruby collection API is probably the one I use the most and also the one I always forget.

🆕 Array#append and Array#prepend

I always forget which method I should use to append or prepend a new element into an array.

Now It’s easy. Ruby 2.5 introduces two new methods Array#append and Array#prepend which are respectively aliases to Array#push and Array#unshift.

http://ruby-doc.org/core-2.5.0/Array.html#method-i-append

Using splat to manipulate an array

If you like pattern matching like in Elixir, you’re going to like this one.

Ok it’s not pattern matching at all but it looks like it. It allows you to easily get elements from an array.

🆕 Hash#slice from ActiveSupport

It’s now a common thing to see introduction of new methods in Ruby coming from Ruby on Rails and especially ActiveSupport.

So it’s no surprise to see the introduction of Hash#slice in Ruby:

http://ruby-doc.org/core-2.5.0/Hash.html#method-i-slice

🆕 Enumerable#{any?,all?,none?,one?} now accept a pattern argument

You can now pass a pattern to all the useful predicate methods from Enumerable.

http://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-all-3F

Enumerable#{min, max}

You can ask Ruby to return more than one element with min and max.

http://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-min

Array#dig and Hash#dig

This method is pretty similar to the [] operator. There’s one subtle difference where dig shines though. It’s when one of the keys or elements you’re trying to parse doesn’t exist. Instead of raising an error dig will return nil.

Let’s take a concrete example with

🆕 Hash#transform_keys and Hash#transform_keys!

Ruby 2.4 introduced the Hash#transform_values method to change all the values of a Hash. It was then logic to add the same logic for the keys of Hash.

http://ruby-doc.org/core-2.5.0/Hash.html#method-i-transform_keys

Modules

Modules in Ruby are super powerful. Here are two methods from Module that help you change the behaviour of a given class.

Module#refine

Refinements only modify classes, not modules. It allows you to change the behaviour of a class only in the current scope meaning if the class is used elsewhere your refinement won’t affect it.

More info: http://ruby-doc.org/core-2.5.0/doc/syntax/refinements_rdoc.html

Module#prepend

If you want to change the behavior once for all regardless of the scope then you should use Module#prepend to properly patch a class:

Misc

Here are some other methods I compiled together that I find also useful but are hard to categorize.

🆕 Object#yield_self

The latest Ruby version also adds a new method named yield_self that do the same thing as tap but instead of returning the “tapped object”, it returns the value returned by the block passed to it.

http://ruby-doc.org/core-2.5.0/Object.html#method-i-yield_self

🆕 Struct now can create classes that accept keyword arguments (kwargs).

Ruby 2.5 introduced support for keyword arguments, you can now use them when using Struct:

http://ruby-doc.org/core-2.5.0/Struct.html#method-c-new

Chomp while using gets

I discovered that since Ruby 2.4 the “gets” method accepts an optional argument to automatically “chomp” the result.

http://ruby-doc.org/core-2.5.0/IO.html#method-i-gets

Float#round

Maybe not a game changer in the way you round float number but since 2.4 you can pass a “half” keyword argument to describe how the method should behave.

🆕 Top-level constant look-up is no longer available

Here is a pretty important change which comes with the new version of Ruby. Before 2.5, if ruby could not find a class in the specified scope it was using the top-level constant of the same name if existing and was emitting a warning. This new version removed the warning message and now raises an error.

It means if you try to call a class without the right scope, Ruby won’t search for it outside of the scope.

‘pp’ is automatically loaded in IRB

You’re gonna like this one! At least, I do.

I can’t count the number of times I use “pp” in an IRB console and got this message:

NoMethodError: undefined method `pp' for main:Object
Did you mean? p
from (irb):1
from /usr/local/bin/irb:11:in `<main>'

You would have to require the library before using it:

It’s over now since this library is automatically loaded when you run a IRB console.

So you can skip the require statement in your IRB now 🙌.

Binding.irb

You may know pry “a powerful alternative to the standard IRB shell for Ruby” and if so then you know that the following command allows you to get a ruby terminal once the code reaches it:

binding.pry

That’s super useful to debug your app. If you don’t want to rely on a external dependency you can still use the same feature using IRB:

binding.irb

You won’t get all the awesome features that come with pry but it can be useful in some use cases.

Conclusion

It’s hard to keep track of the changes in Ruby (I guess it’s true in any programming language) but it’s essential to take some time on a regular basis to review them. I hope you discovered some good new stuff about Ruby while reading this article. This list is not exhaustive at all so feel free to add a comment explaining what you like the most in Ruby that people should know about.

If you want to play with the latest version of Ruby, here are the commands to use depending on your setup:

Rbenv

$ cd "$(rbenv root)"/plugins/ruby-build && git pull
$ rbenv install 2.5
$ rbenv shell 2.5
$ irb
irb(main):001:0>

RVM

$ rvm get stable
$ rvm reload
$ rvm install 2.5
$ rvm use 2.5
$ irb
irb(main):001:0>

Docker

$ docker run --rm -ti ruby:2.5 irb
irb(main):001:0>

Like what you see? Join us, we’re hiring. 🚀

--

--

Mathieu Fosse
Stuart Tech

Co-founder of @useantenna. Former CTO and Co-founder at @tigerlily • @sleekapp. I love writing code, learning things and taking photos.