New Features in ruby 2.6

with the Ruby-2.6 release, you will be enjoying performance improvements and a couple of cool new features. Ruby 2.6 also introduce the initial implementation for JIT (just in time) compiler to improve the performance of ruby programs.

as per the ruby release notes Ruby-2.6 has achieved 1.7x faster performance compared to ruby-2.5 for CPU-intensive tasks.

List of notable new feature add-on source

1) Added alias for Kernel.yield_self as then

It’s a kernel method so available in all ruby objects except BasicObject

don’t be confuse it with tap method.
tap yields self in the block and return self from the block.

then yields self and returns the result of the block.

If you call then with any object without any block it returns the Enumerator object
and if you pass the block it returns the block result.


"my address in town".then
#=> <Enumerator: "my address in town":then>

"my address in town"
.then {|str| str + '?' if str.include?('in') }
.then { |str| str + ' - in City center' if str.include?('address') }
#=> "my address in town? - in City center"

a simple use for this like the | operator transform the data stream using a series of then

2) endless range

using this infinite loop looks clean and more readable as the endless range made the second argument for a range optional.

with syntax (1..) it works as it has no end and we could iterate till infinity 😈

just another random example


even_numbers = []

(1..).each do |index|
  even_numbers << index if index % 2 == 0
  break if even_numbers.count == 10
end

puts even_numbers.then{ |nums| nums.map(&:rationalize) }.join(', ')

3) Adds Enumerator#chain and Enumerator#+

enumerator’s chain method takes other enumerator types as an argument and returns combined object generated form caller enumerator type and given enumerator type.


result = [2, 4, 6].chain([8, 10, 12])
#=> #<Enumerator::Chain: [[2, 4, 6], [8, 10, 12]]>

# return the combined elements
result.to_a
#=> [2, 4, 6, 8, 10, 12]

with ruby-2.6 we can easily combine the enumerators with +


result = [2, 4, 6].to_enum + [8, 10, 12]
#=> #<Enumerator::Chain: [#<Enumerator: [2, 4, 6]:each>, [8, 10, 12]]>

# return the combined elements
result.to_a
#=> [2, 4, 6, 8, 10, 12]

4) Add function composition operator << and >> to Proc and Method

this feature is most famous and indeed will be used a lot who love functional programming.
It provides you the power of composing different functions into a new function.

>> takes another proc object as an argument and returns a new proc object that is the composition of caller proc and another proc and a callable object.

something similar to


f(x) >> h(x) == h(f(x))

and similarly << takes another proc object as an argument and returns a new proc object that is the composition of caller proc and another proc and a callable object.

something similar to


f(x) << h(x) == f(h(x))

ex:


# << example
welcome = ->(name) { "Welcome #{name}" }
with_bang = ->(string) { "#{string}!" }

# composition of two proc
welcome_with_bang = welcome << with_bang

# call composite proc
welcome_with_bang.call('Rakesh')
#=> "Welcome Rakesh!"


# >> example

f = proc {|x| x * x }
g = proc {|x| x + x }

# it works like g(f)
g_f = f >> g

# it works like f(g)
f_g = f << g


g_f[3]
#=> 18

f_g[3]
#=> 36 

5) Adds Binding#source_location

to get more information about the current code context like file name, location and source code line number. And to get this information source_location is our new friend.


# with ruby version < 2.6

binding.eval('[__FILE__, __LINE__]')
#=> ["(irb)", 1]

# with ruby version > 2.6
# we can get the same information with 

binding.source_location
#=> ["(irb)", 2]

binding.source_location is much cleaner and readable and smart choice compare to previous utility binding.eval('[__FILE__, __LINE__]')