What’s new in Ruby 3.3.0

Là một developer có niềm đam mê sâu sắc với Ruby thì chúng ta đều biết vào Giáng sinh hằng năm, Ruby core team sẽ release version Ruby mới. Và năm nay cũng không ngoại lệ, chúng ta sẽ đón chờ phiên bản Ruby 3.3 vào tuần tới.

Mặc dù không có nhiều thay đổi lớn về các tính năng ngôn ngữ như các phiên bản trước, nhưng trong phiên bản này, trọng tâm chính là hiệu suất và trải nghiệm phát triển. Dưới đây là một số điểm nổi bật của phiên bản này:

YJIT

YJIT, trình biên dịch JIT của Ruby, đã có những cải tiến đáng kể trong vài năm qua. Trong năm nay, nó tiếp tục trở nên nhanh hơn, đồng thời tiêu thụ ít bộ nhớ hơn.

Các công ty như BasecampShopify đã sử dụng phiên bản xem trước của 3.3 trong môi trường production và đã thấy sự cải thiện khoảng 15% trong thời gian phản hồi trung bình so với phiên bản 3.3.0 không có YJIT.
Thực tế, YJIT đã rất hiệu quả trong việc tăng tốc ứng dụng Rails và nó sẽ được kích hoạt mặc định trên ứng dụng Rails mới nếu sử dụng Ruby 3.3.

Một phương thức mới, RubyVM::YJIT.enable đã được giới thiệu, cho phép bạn kích hoạt YJIT khi đang chạy. Điều này có thể hữu ích nếu bạn muốn tải ứng dụng nhanh chóng và sau đó kích hoạt YJIT sau khi nó đã khởi động. Đây chính là cách Rails sử dụng để kích hoạt JIT trong một bộ khởi tạo.

RJIT

Một trình biên dịch JIT thử nghiệm có tên là RJIT đã được giới thiệu. Được viết bằng Ruby thuần, nó thay thế MJIT, một JIT thay thế khác đã có sẵn trong Ruby 3.2. RJIT sử dụng nhiều bộ nhớ hơn so với YJIT và chỉ tồn tại cho mục đích thử nghiệm. Trong môi trường sản xuất, vẫn nên sử dụng YJIT.

IRB

Từ khi biết đến Ruby, pry là công cụ gỡ lỗi ưa thích của mình, mình đã chuyển sang sử dụng IRB gần đây, sau khi biết tới bài viết này. Trong phiên bản này, IRB và integration của nó với gem debug đã được cải thiện đến mức pry và byebug không còn cần thiết cho việc gỡ lỗi mã nguồn của bạn.

Range

Rails Range#overlaps?(range)

So sánh hai phạm vi và xem liệu chúng có trùng lặp với nhau không. overlap? trả về true nếu hai phạm vi trùng nhau nếu không thì trả về false.

(3..8).overlaps?(8..10) # => true
(2..43).overlaps?(3..5) # => true
(1..5).overlaps?(7..9) # => false

('a'..'z').overlaps?('c'..'d') # => true

(1.day.from_now..5.days.from_now).overlaps?(5.days.from_now..10.days.from_now) # => false
(1.day.from_now.to_date..5.days.from_now.to_date).overlaps?(5.days.from_now.to_date..10.days.from_now.to_date) # => true

(3...8).overlaps?(8...9) # => false
(3...8).overlaps?(7...9) # => true

# works similarly for open ranges.
(3..).overlaps?(...3) # => false

Ruby < 3.3

Không giống như Rails, Ruby không có phương thức nào để so sánh hai phạm vi và kiểm tra chúng có trùng nhau hay không.

Trước Ruby 3.3, nếu chúng ta muốn kiểm tra sự trùng lặp, chúng ta cần sử dụng phương thức cover, nó sẽ trả về true nếu hai phạm vi trùng nhau.

# Check if range1 covers any value in range2 or vice versa
range1 = (3..8)
range2 = (8..10)
range1.cover?(range2.first) || range2.cover?(range1.first) # => true

range1 = ('a'..'z')
range2 = ('c'..'d')
range1.cover?(range2.first) || range2.cover?(range1.first) # => true

range1 = (1.day.from_now..5.days.from_now)
range2 = (5.days.from_now..10.days.from_now)
range1.cover?(range2.first) || range2.cover?(range1.first) # => false

range1 = (1.day.from_now.to_date..5.days.from_now.to_date)
range2 = (5.days.from_now.to_date..10.days.from_now.to_date)
range1.cover?(range2.first) || range2.cover?(range1.first) # => true

Ruby 3.3

Ruby 3.3 giới thiệu phương thức Range#overlap?(range). Giống như Rails, chúng ta có thể sử dụng overlap? để so sánh hai phạm vi và xem chúng có trùng lặp với nhau không.

  • Nó trả về true nếu hai phạm vi trùng nhau nếu không thì trả về sai.
  • Nó sẽ raise TypeError nếu argument không phải kiểu range
range1 = (3..8)
range2 = (8..10)
range1.overlap?(range2) # => true

range1 = ('a'..'z')
range2 = ('c'..'d')
range1.overlap?(range2) # => true

range1 = (1.day.from_now..5.days.from_now)
range2 = (5.days.from_now..10.days.from_now)
range1.overlap?(range2) # => false

range1 = (1.day.from_now.to_date..5.days.from_now.to_date)
range2 = (5.days.from_now.to_date..10.days.from_now.to_date)
range1.overlap?(range2) # => true

(3..).overlap?(...3) # => false

(3..8).overlap?(3) # => TypeError, argument must be Range


Tham khảo


https://www.ruby-lang.org/en/news/2023/12/11/ruby-3-3-0-rc1-released/
https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-shopify-s-production-code-15-faster/
https://railsatscale.com/2023-12-04-ruby-3-3-s-yjit-faster-while-using-less-memory/

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like