Tìm hiểu về Ruby Refinements
Khi nào và lúc nào chúng ta sử dụng Ruby Refinements cho dự án của mình? Ruby Refinements hay bộ lọc Ruby là 1 tính năng khá mới, được giới thiệu với Ruby 2.0.0. Ở đây chúng tôi xin phép giữ nguyên từ "Ruby Refinements". Ruby Refinements là cái gì? Ruby Refinements là một tính năng tuyệt vời mà ...
Khi nào và lúc nào chúng ta sử dụng Ruby Refinements cho dự án của mình? Ruby Refinements hay bộ lọc Ruby là 1 tính năng khá mới, được giới thiệu với Ruby 2.0.0. Ở đây chúng tôi xin phép giữ nguyên từ "Ruby Refinements".
Ruby Refinements là cái gì?
Ruby Refinements là một tính năng tuyệt vời mà cộng đồng Ruby đã chờ đợi trong một thời gian dài. Nó có mục đích chính để thay thế các đoạn mã với nhưng tác dụng phụ tiêu cực. Lợi thế chính là khả năng mở rộng scope, nghĩa là xác định rõ khu mực mã nó gây ảnh hưởng đến. Refinement là cách làm tốt giúp cho code của bạn dễ hiểu và gọn gàng. Không phải lúc nào chúng ta cũng có thể sử dụng ruby refinement trong dự án của mình. Vì vậy, bây giờ chúng ta hãy đi sâu vào tìm hiểu cách thức hoạt động của nó.
Chúng ta nên sử dụng Ruby Refinements như thế nào?
Để bắt đầu làm việc với Ruby Refinements, việc đầu tiên bạn nên thiết lập các scope mà nó gây ảnh hưởng đến. Vì vậy, chúng ta hãy định nghĩa các module và class
module ListStrings refine String do def +(other) "#{self}, #{other}" end end end
Sau đó sử dụng ListStrings trong khu vực cần required
using ListStrings '4' + '5' # => "4, 5"
Bây giờ, bạn có thể "tinh luyện" đoạn code của bạn. Bạn cũng có thẻ làm điều đó với câu lệnh eval
eval "using ListStrings; '4' + '5'" # => "4, 5"
Hãy nhớ rằng, việc sử dụng sẽ chỉ gây ảnh hưởng đến các file hiện nay, các file khác sẽ không được thay đổi. Bắt đầu từ Ruby 2.3 Refinement có thể được sử dụng trong các class cụ thể, điều đó thật tuyệt, vì nó giúp bảo vệ bạn khỏ tất các hiệu ứng bất lợi
module Foo refine Fixnum do def to_s :foo end end end class NumAsString def num(input) input.to_s end end class NumAsFoo using Foo def num(input) input.to_s end end NumAsString.new.num(4) # => "4" NumAsFoo.new.num(4) # => :foo
Những vấn đề tồn tại của Ruby Refinements là gì?
Ruby Refinements sẽ giúp bạn giới thiệu những cách thay đổi code 1 cách an toàn. Đồng thời nó vẫn có 1 số hạn chế nhất định, vì vậy hãy chú ý điều này. Dưới đây là 1 vài vấn đề mà tôi nhin thấy:
1. Không thể sử dụng nhiều bộ lọc 1 lúc
Bạn sẽ không thể chạy 1 vài bộ lọc cho cùng 1 method, mặc dù đây không phải là 1 trường hợp phổ biến chúng ta thường gặp, nhưng chúng ta vẫn cần phải lưu ý.
2. Không tương thích với Dynamic Dispatch
Dynamic Dispatch được sử dụng gọi các method mapping, ví dụ như
[1,2,3].map(&:to_s)
Thật đang tiếc khi những method này không sử dụng được refinements
3. Kiểm tra lịch sử các đoạn mã
Mộ điểm yếu quan trọng của refinements là làm cho các đoạn khó khăn trong việc thay đổi chúng.
module Bar def refinements require 'set' @refinements = (@refinements || Set.new) << Bar end refine String do def bar :bar end end end class A include Bar and using Bar def a "".bar end end A.new.refinements # => #<Set: {Bar}> A.new.a # => :bar
4. Không thể sử dụng từ bên trong 1 method hoặc 1 module
Nếu bạn muốn sử dụng Refinement, bạn sẽ phải khai báo sử dụng cho phạm vi các scope. Trên phạm vi khác, nó thể có ích cho các developer trong thời gian 1 năm.
Tổng kết
Tóm lại, chúng ta có nên sử dụng chúng hay không? Mặc dù Ruby Refinements, giống như 1 tính năng hữu ích, tuy nhiên vẫn còn 1 số vấn đề nhỏ tồn tại, chúng ta vẫn khuyên bạn nên tin sử dụng nó ngay bây giờ. Sử dụng Ruby Refinements sẽ cho bạn thấy rõ các hành vi thay thế và làm cho code bạn mạch lạc hơn. Và có khả năng rất cao rằng một số nhược điểm của nó sẽ được khắc phục trong tương lai gần nhất, do đó bạn không phải quá lo lắng về điều này
Bài viết được tham khảo và dịch từ: http://blog.rubyroidlabs.com/2016/08/ruby-refinements/