Ruby 2.7.0 đã được phát hành

Đăng bởi naruse vào 25 Dec 2019

Chúng tôi vui mừng thông báo phiên bản Ruby 2.7.0 đã được phát hành.

Phiên bản này giới thiệu một số tính năng mới và cải thiện hiệu suất, đáng chú ý nhất là:

  • Pattern Matching
  • Cải thiện REPL
  • GC nén
  • Tách biệt tham số vị trí và tham số từ khóa

Pattern Matching [Thử nghiệm]

Pattern matching, một tính năng được sử dụng rộng rãi trong các ngôn ngữ lập trình hàm, được giới thiệu như một tính năng thử nghiệm. [Feature #14912]

Nó có thể duyệt qua một đối tượng cho trước và gán giá trị của nó nếu khớp với một mẫu.

require "json"

json = <<END
{
  "name": "Alice",
  "age": 30,
  "children": [{ "name": "Bob", "age": 2 }]
}
END

case JSON.parse(json, symbolize_names: true)
in {name: "Alice", children: [{name: "Bob", age: age}]}
  p age #=> 2
end

Để biết thêm chi tiết, vui lòng xem Pattern matching - New feature in Ruby 2.7.

Cải thiện REPL

irb, môi trường tương tác đi kèm (REPL; Read-Eval-Print-Loop), giờ đây hỗ trợ chỉnh sửa đa dòng. Nó được hỗ trợ bởi reline, một thư viện thuần Ruby tương thích với readline. Nó cũng cung cấp tích hợp rdoc. Trong irb bạn có thể hiển thị tài liệu tham khảo cho một lớp, module, hoặc phương thức cho trước. [Feature #14683], [Feature #14787], [Feature #14918]

Ngoài ra, các dòng mã nguồn hiển thị bởi Binding#irb và kết quả inspect cho các đối tượng lớp core giờ đây được tô màu.

GC nén

Phiên bản này giới thiệu GC nén, có thể chống phân mảnh vùng nhớ bị phân mảnh.

Một số chương trình Ruby đa luồng có thể gây ra phân mảnh bộ nhớ, dẫn đến sử dụng nhiều bộ nhớ và giảm tốc độ.

Phương thức GC.compact được giới thiệu để nén heap. Hàm này nén các đối tượng còn sống trong heap để ít trang bộ nhớ hơn được sử dụng, và heap có thể thân thiện hơn với CoW (copy-on-write). [Feature #15626]

Tách biệt tham số vị trí và tham số từ khóa

Việc chuyển đổi tự động giữa tham số từ khóa và tham số vị trí đã bị phản đối, và việc chuyển đổi sẽ bị loại bỏ trong Ruby 3. [Feature #14183]

Xem bài viết “Separation of positional and keyword arguments in Ruby 3.0” để biết chi tiết. Chỉ các thay đổi được liệt kê như sau.

  • Khi một lời gọi phương thức truyền một Hash ở tham số cuối cùng, và khi nó không truyền từ khóa nào, và khi phương thức được gọi chấp nhận từ khóa, một cảnh báo sẽ được phát ra. Để tiếp tục coi hash như từ khóa, thêm toán tử double splat để tránh cảnh báo và đảm bảo hành vi đúng trong Ruby 3.

    def foo(key: 42); end; foo({key: 42})   # warned
    def foo(**kw);    end; foo({key: 42})   # warned
    def foo(key: 42); end; foo(**{key: 42}) # OK
    def foo(**kw);    end; foo(**{key: 42}) # OK
    
  • Khi một lời gọi phương thức truyền từ khóa cho một phương thức chấp nhận từ khóa, nhưng không truyền đủ tham số vị trí bắt buộc, các từ khóa được coi như tham số vị trí bắt buộc cuối cùng, và một cảnh báo sẽ được phát ra. Truyền tham số dưới dạng hash thay vì từ khóa để tránh cảnh báo và đảm bảo hành vi đúng trong Ruby 3.

    def foo(h, **kw); end; foo(key: 42)      # warned
    def foo(h, key: 42); end; foo(key: 42)   # warned
    def foo(h, **kw); end; foo({key: 42})    # OK
    def foo(h, key: 42); end; foo({key: 42}) # OK
    
  • Khi một phương thức chấp nhận từ khóa cụ thể nhưng không chấp nhận keyword splat, và một hash hoặc keyword splat được truyền cho phương thức bao gồm cả khóa Symbol và non-Symbol, hash sẽ tiếp tục được tách ra, và một cảnh báo sẽ được phát ra. Bạn sẽ cần cập nhật mã gọi để truyền các hash riêng biệt nhằm đảm bảo hành vi đúng trong Ruby 3.

    def foo(h={}, key: 42); end; foo("key" => 43, key: 42)   # warned
    def foo(h={}, key: 42); end; foo({"key" => 43, key: 42}) # warned
    def foo(h={}, key: 42); end; foo({"key" => 43}, key: 42) # OK
    
  • Nếu một phương thức không chấp nhận từ khóa, và được gọi với từ khóa, các từ khóa vẫn được coi như một hash vị trí, không có cảnh báo. Hành vi này sẽ tiếp tục hoạt động trong Ruby 3.

    def foo(opt={});  end; foo( key: 42 )   # OK
    
  • Non-symbol được phép làm khóa tham số từ khóa nếu phương thức chấp nhận từ khóa tùy ý. [Feature #14183]

    def foo(**kw); p kw; end; foo("str" => 1) #=> {"str"=>1}
    
  • **nil được phép trong định nghĩa phương thức để đánh dấu rõ ràng rằng phương thức không chấp nhận từ khóa. Gọi phương thức như vậy với từ khóa sẽ dẫn đến ArgumentError. [Feature #14183]

    def foo(h, **nil); end; foo(key: 1)       # ArgumentError
    def foo(h, **nil); end; foo(**{key: 1})   # ArgumentError
    def foo(h, **nil); end; foo("str" => 1)   # ArgumentError
    def foo(h, **nil); end; foo({key: 1})     # OK
    def foo(h, **nil); end; foo({"str" => 1}) # OK
    
  • Truyền một keyword splat rỗng cho một phương thức không chấp nhận từ khóa sẽ không còn truyền một hash rỗng, trừ khi hash rỗng là cần thiết cho một tham số bắt buộc, trong trường hợp đó một cảnh báo sẽ được phát ra. Loại bỏ double splat để tiếp tục truyền một hash vị trí. [Feature #14183]

    h = {}; def foo(*a) a end; foo(**h) # []
    h = {}; def foo(a) a end; foo(**h)  # {} and warning
    h = {}; def foo(*a) a end; foo(h)   # [{}]
    h = {}; def foo(a) a end; foo(h)    # {}
    

Nếu bạn muốn tắt cảnh báo phản đối, vui lòng sử dụng tham số dòng lệnh -W:no-deprecated hoặc thêm Warning[:deprecated] = false vào mã của bạn.

Các tính năng mới đáng chú ý khác

  • Tham số đánh số được giới thiệu như tham số block mặc định. [Feature #4475]

  • Range không có điểm đầu được giới thiệu ở dạng thử nghiệm. Nó có thể không hữu ích như range không có điểm cuối, nhưng sẽ tốt cho mục đích DSL. [Feature #14799]

    ary[..3]  # identical to ary[0..3]
    rel.where(sales: ..100)
    
  • Enumerable#tally được thêm vào. Nó đếm số lần xuất hiện của mỗi phần tử.

    ["a", "b", "c", "b"].tally
    #=> {"a"=>1, "b"=>2, "c"=>1}
    
  • Gọi phương thức private với self tường minh làm receiver giờ đây được cho phép. [Feature #11297], [Feature #16123]

    def foo
    end
    private :foo
    self.foo
    
  • Enumerator::Lazy#eager được thêm vào. Nó tạo ra một enumerator không lazy từ một enumerator lazy. [Feature #15901]

    a = %w(foo bar baz)
    e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager
    p e.class               #=> Enumerator
    p e.map {|x| x + "?" }  #=> ["FOO!?", "BAR!?", "BAZ!?"]
    

Cải thiện hiệu suất

  • JIT [Thử nghiệm]

    • Mã JIT được biên dịch lại thành mã ít tối ưu hơn khi một giả định tối ưu hóa bị vô hiệu.

    • Method inlining được thực hiện khi một phương thức được coi là thuần túy. Tối ưu hóa này vẫn đang thử nghiệm và nhiều phương thức vẫn CHƯA được coi là thuần túy.

    • Giá trị mặc định của --jit-min-calls được thay đổi từ 5 thành 10,000.

    • Giá trị mặc định của --jit-max-cache được thay đổi từ 1,000 thành 100.

  • Chiến lược cache của Fiber được thay đổi và việc tạo fiber được tăng tốc. GH-2224

  • Module#name, true.to_s, false.to_s, và nil.to_s giờ đây luôn trả về một String đã frozen. String được trả về luôn giống nhau cho một đối tượng cho trước. [Thử nghiệm] [Feature #16150]

  • Hiệu suất của CGI.escapeHTML được cải thiện. GH-2226

  • Hiệu suất của Monitor và MonitorMixin được cải thiện. [Feature #16255]

  • Cache phương thức theo vị trí gọi, đã có từ khoảng phiên bản 1.9, đã được cải thiện: tỷ lệ cache hit tăng từ 89% lên 94%. Xem GH-2583

  • RubyVM::InstructionSequence#to_binary tạo binary đã biên dịch. Kích thước binary được giảm. [Feature #16163]

Các thay đổi đáng chú ý khác kể từ 2.6

  • Một số thư viện chuẩn được cập nhật.
  • Các thư viện sau không còn là bundled gems. Cài đặt gem tương ứng để sử dụng các tính năng này.
    • CMath (cmath gem)
    • Scanf (scanf gem)
    • Shell (shell gem)
    • Synchronizer (sync gem)
    • ThreadsWait (thwait gem)
    • E2MM (e2mmap gem)
  • profile.rb đã bị loại bỏ khỏi thư viện chuẩn.

  • Chuyển stdlib thành default gems
    • Các default gems sau đã được xuất bản trên rubygems.org
      • benchmark
      • cgi
      • delegate
      • getoptlong
      • net-pop
      • net-smtp
      • open3
      • pstore
      • singleton
    • Các default gems sau chỉ được chuyển tại ruby-core, nhưng chưa được xuất bản trên rubygems.org.
      • monitor
      • observer
      • timeout
      • tracer
      • uri
      • yaml
  • Proc.newproc không có block trong phương thức được gọi với block giờ đây sẽ cảnh báo.

  • lambda không có block trong phương thức được gọi với block sẽ phát sinh ngoại lệ.

  • Cập nhật phiên bản Unicode và Emoji từ 11.0.0 lên 12.0.0. [Feature #15321]

  • Cập nhật phiên bản Unicode lên 12.1.0, thêm hỗ trợ cho U+32FF SQUARE ERA NAME REIWA. [Feature #15195]

  • Date.jisx0301, Date#jisx0301, và Date.parse hỗ trợ niên hiệu Nhật Bản mới. [Feature #15742]

  • Yêu cầu trình biên dịch hỗ trợ C99. [Misc #15347]

Xem NEWS hoặc nhật ký commit để biết thêm chi tiết.

Với những thay đổi đó, 4190 tệp đã thay đổi, 227498 thêm vào(+), 99979 xóa đi(-) kể từ Ruby 2.6.0!

Chúc mừng Giáng sinh, chúc mừng ngày lễ, và hãy tận hưởng lập trình với Ruby 2.7!

Tải về

  • https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.bz2

    SIZE: 14703381
    SHA1: b54f4633174dbc55db77d9fd6d0ef90cc35503af
    SHA256: 7aa247a19622a803bdd29fdb28108de9798abe841254fe8ea82c31d125c6ab26
    SHA512: 8b8dd0ceba65bdde53b7c59e6a84bc6bf634c676bfeb2ff0b3604c362c663b465397f31ff6c936441b3daabb78fb7a619be5569480c95f113dd0453488761ce7
    
  • https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.gz

    SIZE: 16799684
    SHA1: 6f4e99b5556010cb27e236873cb8c09eb8317cd5
    SHA256: 8c99aa93b5e2f1bc8437d1bbbefd27b13e7694025331f77245d0c068ef1f8cbe
    SHA512: 973fc29b7c19e96c5299817d00fbdd6176319468abfca61c12b5e177b0fb0d31174a5a5525985122a7a356091a709f41b332454094940362322d1f42b77c9927
    
  • https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.tar.xz

    SIZE: 11990900
    SHA1: 943c767cec037529b8e2d3cc14fc880cad5bad8d
    SHA256: 27d350a52a02b53034ca0794efe518667d558f152656c2baaf08f3d0c8b02343
    SHA512: dd5690c631bf3a2b76cdc06902bcd76a89713a045e136debab9b8a81ff8c433bbb254aa09e4014ca1cf85a69ff4bcb13de11da5e40c224e7268be43ef2194af7
    
  • https://cache.ruby-lang.org/pub/ruby/2.7/ruby-2.7.0.zip

    SIZE: 20571744
    SHA1: fbebdd3a2a641f9a81f7d8db5abd926acea27e80
    SHA256: 8bf2050fa1fc76882f878fd526e4184dc54bd402e385efa80ef5fd3b810522e0
    SHA512: 5060f2dd3bfd271ef255b17589d6d014260d7ec2d97b48112b717ee01c62fe125c3fe04f813e02d607cea3f0a2a812b14eb3a28d06c2551354dfeff5f4c3dd6b
    

Ruby là gì

Ruby được phát triển lần đầu bởi Matz (Yukihiro Matsumoto) vào năm 1993, và hiện được phát triển dưới dạng Mã nguồn Mở. Nó chạy trên nhiều nền tảng và được sử dụng trên toàn thế giới, đặc biệt cho phát triển web.

Tin mới nhất

Phát hành Ruby 4.0.0

Chúng tôi vui mừng thông báo phát hành Ruby 4.0.0. Ruby 4.0 giới thiệu “Ruby Box” và “ZJIT”, cùng nhiều cải tiến khác.

Đăng bởi naruse vào 25 Dec 2025

Diện mạo mới cho tài liệu Ruby

Tiếp theo việc thiết kế lại ruby-lang.org, chúng tôi có thêm tin vui để kỷ niệm 30 năm Ruby: docs.ruby-lang.org có diện mạo hoàn toàn...

Đăng bởi Stan Lo vào 23 Dec 2025

Thêm Tin...