Vào ngày 25 tháng 12 sắp tới, phiên bản Ruby 2.7 sẽ chính thức được phát hành. Đây cũng chính là phiên bản cuối cùng trước khi chúng ta sẽ đến với Ruby 3.0. Trong quá trình làm việc, Ruby thực sự đã khiến cho các lập trình viên cảm thấy thoải mái, điều mà nó luôn hướng tới. Vậy hãy cùng xem trong phiên bản mới này, Ruby sẽ mang đến cho chúng ta thêm những gì nữa.
Pattern Matching
Đây là một tính năng mà theo mình sẽ là đáng để chờ đợi nhất trong phiên bản Ruby 2.7 này. Nó làm mình liên tưởng tới tính năng Destructuring assignment trong ES6, nhưng Ruby còn làm được nhiều hơn thế. Về cơ bản Pattern Matching
kết hợp giữa destructuring
và specifying patterns
. Chúng ta sẽ cùng xem các ví dụ dưới đây để hiểu rõ hơn:
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> |
Chúng ta cũng có thể sử dụng partern matching với những kiểu dữ liệu phức tạp hơn:
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
Trong các block mặc định của Ruby, các tham số có thể được yield vào. Chắc hẳn chúng ta đã quá quen thuộc với những đoạn code như dưới đây:
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> |
Tuy nhiên ở phiên bản mới này các tham số sẽ được đánh số thứ tự, và ta có thể viết lại như sau:
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> |
Đây là một tính năng thử nghiệm, tuy ngắn gọn hơn nhưng nó cũng phải trả một cái giá đó là đoạn code sẽ phần nào mất đi sự rõ ràng.
Enumerable#tally
Đây là một method mới có nhiệm vụ là đếm số lần suất hiện của một phần tử trong array
và trả về một hash
với những giá trị tương ứng
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 |
Và đây sẽ là kết quả trả về
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
Đúng như tên gọi của nó, đây là sự kết hợp của 2 method mà chúng ta đã rất quen thuộc ở các phiên bản trước là select
và map
Ví dụ, khi muốn lấy ra những số chẵn rồi sau đó chuyển chúng về dạng string thì chúng ta có thể làm như sau:
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> |
Nhưng nếu bạn muốn ngắn gọn hơn nữa thì có thể sử dụng:
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
Thực ra có thể xem đây là alias của toán tử &
mà chúng ta đã từng biết trước đó:
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> |
Với intersection
chúng sẽ được viết lại như sau:
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> |
Chúng ta sẽ thu về cùng một kết quả tuy nhiên việc sử dụng intersection
trông sẽ rõ ràng và hướng đối tượng hơn
Enumerator.produce
Đây là một tính năng mới khá thú vị và hữu ích. Cơ chế làm việc của nó là sẽ tạo ra một tập hợp vô hạn bằng việc xác định phần tử tiếp theo dựa vào một phần tử trước đó:
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> |
Trên đây là một ví dụ trong việc sử dụng produce
trong việc tính lỹ thừa của 2
Beginless Ranges
Một sự thay đổi khác nữa và cũng là một cách để tạo ra một nửa khoảng tập hợp vô hạn đó là việc không sử dụng giá trị cho các đầu mút của một Range
. Đây là một tính năng thử nghiệm và chủ yếu dùng để so sánh hay kiểm tra một phần tử có nằm trong tập hợp nào đó hay không:
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> |
Một vài thay đổi khác
Symbol#start_with?
/Symbol#end_with?
: đây là những method đã được sử dụng cho các chuỗiString
, với phiên bản mới này chúng ta đã có thể sử dụng nó cho cácSymbol
- Khi một method định nghĩa một dối số là
**nil
thì sẽ được hiểu là method này không nhận một keyword nào cả - Module GC sẽ được cải tiến để làm việc hiệu quả hơn trong việc cải thiện phân mảnh bộ nhớ
- Cải tiến về thread giúp cho việc chạy đa luồng nhanh hơn
Summary
Vừa rồi mình đã gửi đến các bạn một số tính năng mới cũng như các thay đổi trong phiên bản Ruby 2.7 sẽ được phát hành trong thời gian sắp tới. Đây cũng là thời điểm tốt nhất để chúng ta cùng nhìn lại những điều mà Ruby đã mang đến và chuẩn bị cho một sự thay đổi lớn hơn ở phiên bản Ruby 3.0
(Bài viết có tham khảo các nguồn trên Internet)