It's Christmas day and as per the tradition the Ruby core team will release Ruby 2.7 today. Ruby 2.7 is last release before the big major version upgrade to Ruby 3.0 coming up in 2020. Ruby 2.7 has lot of interesting features, some changes that you may not like, some changes that you will definitely like. It also builds the foundation for Ruby 3 by introducing warnings, deprecations and experimental features. In this post, you will learn everything that you need to know about Ruby 2.7
Improved IRB
The IRB now supports syntax highlighting, inline editing of methods. It also supports auto completion. It auto indents the code as we type.
Numbered parameters
We can access the arguments passed to the block by using _1
_2
etc.
[1, 2, 10].map { _1.to_s(16) } #=> ["1", "2", "a"]
I found out that this feature seems to be really useful when there is only argument being passed to the block.
For eg.
[1,2,3].map { _1 * 3 }
=> [3, 6, 9]
You can also use it with blocks which get multiple arguments.
[1,2].each_with_index { p _1 }
1
2
=> [1, 2]
[1,2].each_with_index { p _2 }
0
1
=> [1, 2]
Discussion -
https://bugs.ruby-lang.org/issues/4475
https://bugs.ruby-lang.org/issues/15723
Argument forwarding
This is really cool feature. If you want to just pass all the arguments of the current method to a new method, Ruby 2.7 makes it dead easy with the help (...)
.
def hello(...)
Greeter.new.hello(...)
end
The paranthesis around
...
are mandatory.
Discussion -
https://bugs.ruby-lang.org/issues/16253
Manual compaction of Ruby's GC
A new method GC.compact
is introduced to compact Ruby's GC so as to reduce the heap fragmentation. This operation runs a full GC, compacts the heap and then runs full GC again. The GC.compact
method can be called by library authors to compact the GC. Application developers mostly will not need to call it as part of the application code. For eg. Puma now compacts GC just before the fork.
Aaron's talk linked below on this topic is worth checking out to understand how this feature works and what problems it tries to solve.
Discussion -
https://bugs.ruby-lang.org/issues/15626
Benchmark -
https://gist.github.com/tenderlove/99112e9fcc85d9c6c7d9d0ea40063fc6
Aaron's talk from Rubyconf 2019 -
https://www.youtube.com/watch?v=1F3gXYhQsAY&feature=emb_title
Introducing FrozenError#receiver
FrozenError is raised when we try to modify a frozen object. The receiver
method will return the object on which modification was attempted. This will help in debugging.
In the docs it is mentioned that when you are raising FrozenError, the second argument can be passed as the receiver
object but I am getting an error if I pass second argument to FrozenError
on Ruby 2.7.0-rc2.
FrozenError.new("error message", "receiver")
Traceback (most recent call last):
5: from (irb):68
4: from (irb):69:in `rescue in irb_binding'
3: from (irb):69:in `new'
2: from (irb):69:in `initialize'
1: from (irb):69:in `initialize'
ArgumentError (wrong number of arguments (given 2, expected 0..1))
Introducing Module#const_source_location
Method#source_location
is my favourite debugging method. It returns the location where a method is defined. Similarly, Module#const_source_location
will return location where the constant is defined.
Repo.const_source_location(:CLASS_FOR_DOC_LANGUAGE)
=> ["/Users/prathamesh/Projects/sources/codetriage/app/models/repo.rb", 23]
Discussion -
https://bugs.ruby-lang.org/issues/10771
Real keyword arguments
Biggest change in Ruby 2.7 which has maximum impact in all of our existing code is with the way keyword arguments will be handled in Ruby going forward.
Before Ruby 2.7, the keyword argument is a normal argument that is a Hash object and is passed as the last argument. In Ruby 3, a keyword argument will be completely separated from normal arguments like a block parameter that is also completely separated from normal arguments. In Ruby 2.7 a warning is displayed when a normal argument is used instead of keyword argument. If you try to run a Rails app on Ruby 2.7, your terminal will be filled with warnings such as:
/Users/prathamesh/.rbenv/versions/2.7.0-rc2/lib/ruby/gems/2.7.0/gems/activerecord-6.0.2/lib/active_record/type.rb:27: warning: The last argument is used as keyword parameters; maybe ** should be added to the call
/Users/prathamesh/.rbenv/versions/2.7.0-rc2/lib/ruby/gems/2.7.0/gems/mustermann-1.0.3/lib/mustermann/ast/compiler.rb:43: warning: The last argument is used as keyword parameters; maybe ** should be added to the call
This change is causing the logs flooded with these warnings. This change is explained here with possible solutions. If you are using Rails, there are lot of warnings related to this change. But they are being fixed one by one. We will have to wait for a Ruby 2.7 compatible Rails release to get rid of all of the warnings.
And much more..
There are so many changes that I have not covered in this blog post. Honourable mentions are Enumerable#tally, Enumerable#filter_map, begin and endless ranges. For full list of changes, checkout this.
Bonus
If you are on Heroku, you can give Ruby 2.7 try at this very moment because it is already available 🥳 https://blog.heroku.com/ruby-2-7-0-holiday-release
If you are using chruby
or rbenv
, Ruby 2.7.0 is available for installation. Ruby core team has provided a docker image for Ruby 2.7.0 as well. You can use it as follows:
docker run -it --rm rubylang/ruby irb
Ruby 2.7.0 is also available on Travis CI. It is not yet available on Circle CI.
Happy holidays and happy hacking with Ruby 2.7!
Top comments (0)