On December 25, Ruby 2.7 will be officially released. This is also the last version before we will come to Ruby 3.0 . In the process of working, Ruby really made the programmers feel comfortable, which it always aims to. So let’s take a look in this new version, Ruby will bring us more more.
Pattern Matching
This is a feature that I think will be the most worth waiting for in this Ruby 2.7 version. It reminds me of the Destructuring assignment feature in ES6, but Ruby does more than that. Basically Pattern Matching
combines destructuring
and specifying patterns
. We will see the examples below to better understand:
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token keyword">case</span> <span class="token number">0</span> <span class="token keyword">in</span> <span class="token number">0</span> <span class="token symbol">:match</span> <span class="token keyword">end</span> <span class="token comment">#=> :match</span> <span class="token keyword">case</span> <span class="token number">0</span> <span class="token keyword">in</span> <span class="token number">3.</span> <span class="token number">.6</span> <span class="token symbol">:no_match</span> <span class="token keyword">end</span> <span class="token comment">#=> NoMatchingPatternError (0)</span> |
We can also use partern matching with more complex data types:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">case</span> <span class="token string">"A String"</span> <span class="token keyword">in</span> <span class="token builtin">String</span> <span class="token symbol">:match</span> <span class="token keyword">end</span> <span class="token keyword">case</span> <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token keyword">in</span> <span class="token punctuation">[</span> _ <span class="token punctuation">,</span> a <span class="token punctuation">]</span> a <span class="token keyword">end</span> <span class="token comment">#=> 1</span> <span class="token keyword">case</span> <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">]</span> <span class="token keyword">in</span> <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">,</span> <span class="token operator">*</span> tail <span class="token punctuation">]</span> tail <span class="token keyword">end</span> <span class="token comment">#=> [1, 2]</span> <span class="token keyword">case</span> <span class="token punctuation">{</span> a <span class="token punctuation">:</span> <span class="token number">0</span> <span class="token punctuation">,</span> b <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> c <span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token keyword">in</span> <span class="token punctuation">{</span> a <span class="token punctuation">:</span> <span class="token number">0</span> <span class="token punctuation">,</span> b <span class="token punctuation">:</span> b <span class="token punctuation">,</span> c <span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">}</span> b <span class="token keyword">end</span> <span class="token comment">#=> 1</span> |
Numbered Parameters
In Ruby’s default blocks, parameters can be yielded. Surely we are familiar with the code as follows:
1 2 3 | <span class="token punctuation">(</span> <span class="token number">1.</span> <span class="token number">.3</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token keyword">each</span> <span class="token punctuation">{</span> <span class="token operator">|</span> x <span class="token operator">|</span> puts x <span class="token punctuation">}</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> sort <span class="token punctuation">{</span> <span class="token operator">|</span> a <span class="token punctuation">,</span> b <span class="token operator">|</span> b <span class="token operator"><=</span> <span class="token operator">></span> a <span class="token punctuation">}</span> |
However, in this new version, the parameters will be numbered, and we can rewrite the following:
1 2 3 | <span class="token punctuation">(</span> <span class="token number">1.</span> <span class="token number">.3</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token keyword">each</span> <span class="token punctuation">{</span> puts _1 <span class="token punctuation">}</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">5</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> sort <span class="token punctuation">{</span> _2 <span class="token operator"><=</span> <span class="token operator">></span> _1 <span class="token punctuation">}</span> |
This is an experimental feature, although shorter, but it also has to pay a price that the code will somewhat lose clarity.
Enumerable # tally
This is a new method that counts the number of occurrences of an element in the array
and returns a hash
with corresponding values.
1 2 | <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token string">"one"</span> <span class="token punctuation">,</span> <span class="token string">"two"</span> <span class="token punctuation">,</span> <span class="token string">"one"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> tally |
And this will be the result returned
1 2 | <span class="token punctuation">{</span> <span class="token string">"1"</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token string">"2"</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token string">"one"</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token string">"two"</span> <span class="token operator">=</span> <span class="token operator">></span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span> tally |
Enumerable # filter_map
As the name implies, this is a combination of two methods that we are familiar with in previous versions, select
and map
example, when you want to retrieve even numbers and then convert them to a string, We can do the following:
1 2 | <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> select <span class="token punctuation">{</span> <span class="token operator">|</span> number <span class="token operator">|</span> number <span class="token punctuation">.</span> even <span class="token operator">?</span> <span class="token punctuation">}</span> <span class="token punctuation">.</span> map <span class="token punctuation">{</span> <span class="token operator">|</span> number <span class="token operator">|</span> number <span class="token punctuation">.</span> to_s <span class="token punctuation">}</span> |
But if you want to be more concise, you can use:
1 2 | <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> filter_map <span class="token punctuation">{</span> <span class="token operator">|</span> number <span class="token operator">|</span> number <span class="token punctuation">.</span> to_s <span class="token keyword">if</span> number <span class="token punctuation">.</span> even <span class="token operator">?</span> <span class="token punctuation">}</span> |
Array # intersection
In fact, this is the alias of the &
operator we have known before:
1 2 3 | <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">]</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token comment">#=> [1, 2]</span> <span class="token punctuation">[</span> <span class="token string">"a"</span> <span class="token punctuation">,</span> <span class="token string">"b"</span> <span class="token punctuation">,</span> <span class="token string">"c"</span> <span class="token punctuation">]</span> <span class="token operator">&</span> <span class="token punctuation">[</span> <span class="token string">"b"</span> <span class="token punctuation">,</span> <span class="token string">"c"</span> <span class="token punctuation">,</span> <span class="token string">"d"</span> <span class="token punctuation">]</span> <span class="token comment">#=> ["b", "c"]</span> |
With intersection
they will be rewritten as follows:
1 2 3 | <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> intersection <span class="token punctuation">[</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token comment">#=> [1, 2]</span> <span class="token punctuation">[</span> <span class="token string">"a"</span> <span class="token punctuation">,</span> <span class="token string">"b"</span> <span class="token punctuation">,</span> <span class="token string">"c"</span> <span class="token punctuation">]</span> <span class="token punctuation">.</span> intersection <span class="token punctuation">[</span> <span class="token string">"b"</span> <span class="token punctuation">,</span> <span class="token string">"c"</span> <span class="token punctuation">,</span> <span class="token string">"d"</span> <span class="token punctuation">]</span> <span class="token comment">#=> ["b", "c"]</span> |
We will get the same result however using intersection
will look clearer and more object oriented
Enumerator.produce
This is a pretty interesting and useful new feature. Its working mechanism is to create an infinite set by defining the next element based on an earlier element:
1 2 3 4 | produce <span class="token operator">=</span> <span class="token constant">Enumerator</span> <span class="token punctuation">.</span> <span class="token function">produce</span> <span class="token punctuation">(</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token operator">|</span> previous_number <span class="token operator">|</span> previous_number <span class="token operator">*</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> produce <span class="token punctuation">.</span> <span class="token function">take</span> <span class="token punctuation">(</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> last <span class="token comment">#=> 4</span> produce <span class="token punctuation">.</span> <span class="token function">take</span> <span class="token punctuation">(</span> <span class="token number">4</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> last <span class="token comment">#=> 16</span> |
The above is an example of using produce
in the power of 2
Beginless Ranges
Another change, and one way to create half the infinite set, is to not use the values for the ends of a Range
. This is an experimental feature and is mainly used to compare or test an element in a given set:
1 2 3 4 5 6 7 8 9 | <span class="token keyword">case</span> date <span class="token keyword">when</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token constant">Date</span> <span class="token punctuation">.</span> today <span class="token symbol">:past</span> <span class="token keyword">when</span> <span class="token constant">Date</span> <span class="token punctuation">.</span> today <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token symbol">:feture</span> <span class="token keyword">else</span> <span class="token symbol">:now</span> <span class="token keyword">end</span> |
A few other changes
Symbol#start_with?
/Symbol#end_with?
: these are the methods that have been used forString
strings, with this new version we can use it forSymbol
- When a method defines a numeric value as
**nil
, it will be understood that this method does not receive a keyword at all - The GC module will be improved to work more effectively in improving memory fragmentation
- Thread enhancements make multithreading faster
Summary
Recently I have sent you some new features as well as changes in Ruby 2.7 version will be released in the near future. This is also the best time for us to look back on what Ruby has brought and prepare for a bigger change in Ruby 3.0
(The article has references to sources on the Internet)