Phát hành Ruby 3.2.0 Preview 3
Đăng bởi naruse vào 11 Nov 2022
Chúng tôi vui mừng thông báo phát hành Ruby 3.2.0-preview3. Ruby 3.2 bổ sung nhiều tính năng và cải thiện hiệu suất.
Hỗ trợ WebAssembly dựa trên WASI
Đây là bản port ban đầu của hỗ trợ WebAssembly dựa trên WASI. Bản port này cho phép tệp nhị phân CRuby có thể sử dụng trên trình duyệt Web, môi trường Serverless Edge và các trình nhúng WebAssembly/WASI khác. Hiện tại bản port này vượt qua các bộ test cơ bản và bootstrap mà không sử dụng Thread API.

Bối cảnh
WebAssembly (Wasm) ban đầu được giới thiệu để chạy chương trình một cách an toàn và nhanh chóng trên trình duyệt web. Nhưng mục tiêu của nó - chạy chương trình hiệu quả với bảo mật trên nhiều môi trường khác nhau - đã được mong đợi từ lâu không chỉ cho web mà còn cho các ứng dụng nói chung.
WASI (The WebAssembly System Interface) được thiết kế cho các trường hợp sử dụng như vậy. Mặc dù các ứng dụng này cần giao tiếp với hệ điều hành, WebAssembly chạy trên một máy ảo không có giao diện hệ thống. WASI chuẩn hóa điều đó.
Hỗ trợ WebAssembly/WASI trong Ruby nhằm tận dụng các dự án này. Nó cho phép các nhà phát triển Ruby viết ứng dụng chạy trên nền tảng đầy hứa hẹn đó.
Trường hợp sử dụng
Hỗ trợ này khuyến khích các nhà phát triển có thể sử dụng CRuby trong môi trường WebAssembly. Một ví dụ trường hợp sử dụng là hỗ trợ CRuby của TryRuby playground. Bây giờ bạn có thể thử CRuby gốc ngay trong trình duyệt web của mình.
Các điểm kỹ thuật
WASI và WebAssembly hiện tại vẫn thiếu một số tính năng để triển khai Fiber, exception và GC vì nó vẫn đang phát triển và cũng vì lý do bảo mật. Vì vậy CRuby lấp đầy khoảng trống bằng cách sử dụng Asyncify, một kỹ thuật chuyển đổi nhị phân để điều khiển thực thi trong userland.
Ngoài ra, chúng tôi đã xây dựng VFS trên WASI để có thể dễ dàng đóng gói ứng dụng Ruby thành một tệp .wasm duy nhất. Điều này giúp việc phân phối ứng dụng Ruby dễ dàng hơn một chút.
Liên kết liên quan
Cải thiện Regexp chống ReDoS
Được biết rằng việc khớp Regexp có thể mất thời gian dài bất ngờ. Nếu mã của bạn cố gắng khớp một Regexp có thể không hiệu quả với đầu vào không tin cậy, kẻ tấn công có thể khai thác nó để tấn công từ chối dịch vụ hiệu quả (gọi là Regular expression DoS, hoặc ReDoS).
Chúng tôi đã giới thiệu hai cải tiến giúp giảm thiểu đáng kể ReDoS.
Cải thiện thuật toán khớp Regexp
Kể từ Ruby 3.2, thuật toán khớp của Regexp đã được cải thiện đáng kể bằng kỹ thuật ghi nhớ (memoization).
# This matching takes 10 sec. in Ruby 3.1, and does 0.003 sec. in Ruby 3.2
/^a*b?a*$/ =~ "a" * 50000 + "x"
Thuật toán khớp cải tiến cho phép hầu hết các phép khớp Regexp (khoảng 90% trong các thí nghiệm của chúng tôi) được hoàn thành trong thời gian tuyến tính.
(Cho người dùng preview: tối ưu hóa này có thể tiêu thụ bộ nhớ tỷ lệ thuận với độ dài đầu vào cho mỗi lần khớp. Chúng tôi dự kiến không có vấn đề thực tế nào phát sinh vì việc cấp phát bộ nhớ này thường bị trì hoãn, và một phép khớp Regexp bình thường nên tiêu thụ tối đa 10 lần bộ nhớ so với độ dài đầu vào. Nếu bạn hết bộ nhớ khi khớp Regexp trong ứng dụng thực tế, vui lòng báo cáo.)
Đề xuất ban đầu là https://bugs.ruby-lang.org/issues/19104
Thời gian chờ Regexp
Tối ưu hóa ở trên không thể áp dụng cho một số loại biểu thức chính quy, chẳng hạn như những biểu thức bao gồm các tính năng nâng cao (ví dụ: tham chiếu ngược hoặc look-around), hoặc với số lần lặp cố định lớn. Như một biện pháp dự phòng, tính năng thời gian chờ cho khớp Regexp cũng được giới thiệu.
Regexp.timeout = 1.0
/^a*b?a*()\1$/ =~ "a" * 50000 + "x"
#=> Regexp::TimeoutError is raised in one second
Lưu ý rằng Regexp.timeout là cấu hình toàn cục. Nếu bạn muốn sử dụng các cài đặt thời gian chờ khác nhau cho một số Regexp đặc biệt, bạn có thể sử dụng từ khóa timeout cho Regexp.new.
Regexp.timeout = 1.0
# This regexp has no timeout
long_time_re = Regexp.new('^a*b?a*()\1$', timeout: Float::INFINITY)
long_time_re =~ "a" * 50000 + "x" # never interrupted
Đề xuất ban đầu là https://bugs.ruby-lang.org/issues/17837
Các tính năng mới đáng chú ý khác
Không còn đi kèm mã nguồn bên thứ ba
-
Chúng tôi không còn đi kèm mã nguồn bên thứ ba như
libyaml,libffi.-
Mã nguồn libyaml đã được xóa khỏi psych. Bạn có thể cần cài đặt
libyaml-devtrên nền tảng Ubuntu/Debian. Tên gói khác nhau trên mỗi nền tảng. -
Mã nguồn libffi đi kèm cũng đã được xóa khỏi
fiddle
-
Ngôn ngữ
-
Các tham số rest và keyword rest ẩn danh giờ đây có thể được truyền làm đối số, thay vì chỉ được sử dụng trong tham số phương thức. [Feature #18351]
def foo(*) bar(*) end def baz(**) quux(**) end -
Một proc nhận một tham số vị trí duy nhất và từ khóa sẽ không còn tự động tách (autosplat). [Bug #18633]
proc{|a, **k| a}.call([1, 2]) # Ruby 3.1 and before # => 1 # Ruby 3.2 and after # => [1, 2] -
Thứ tự đánh giá gán hằng số cho các hằng số được đặt trên đối tượng tường minh đã được làm nhất quán với thứ tự đánh giá gán thuộc tính đơn. Với mã này:
foo::BAR = bazfoogiờ được gọi trướcbaz. Tương tự, cho các phép gán đa hằng số, thứ tự đánh giá từ trái sang phải được sử dụng. Với mã này:foo1::BAR1, foo2::BAR2 = baz1, baz2Thứ tự đánh giá sau đây được sử dụng:
foo1foo2baz1baz2
-
Find pattern không còn là tính năng thử nghiệm. [Feature #18585]
-
Các phương thức nhận tham số rest (như
*args) và muốn ủy quyền tham số từ khóa quafoo(*args)giờ phải được đánh dấu bằngruby2_keywords(nếu chưa có). Nói cách khác, tất cả các phương thức muốn ủy quyền tham số từ khóa qua*argsgiờ phải được đánh dấu bằngruby2_keywords, không có ngoại lệ. Điều này sẽ giúp dễ dàng chuyển sang các cách ủy quyền khác khi thư viện có thể yêu cầu Ruby 3+. Trước đây, cờruby2_keywordsđược giữ lại nếu phương thức nhận nhận*args, nhưng đây là lỗi và không nhất quán. Một kỹ thuật tốt để tìm cácruby2_keywordscó thể bị thiếu là chạy bộ test, tìm nơi test thất bại và tìm phương thức cuối phải nhận tham số từ khóa, sử dụngputs nil, caller, nilở đó, rồi kiểm tra từng phương thức/block trên chuỗi gọi phải ủy quyền từ khóa được đánh dấu đúng bằngruby2_keywords. [Bug #18625] [Bug #16466]def target(**kw) end # Accidentally worked without ruby2_keywords in Ruby 2.7-3.1, ruby2_keywords # needed in 3.2+. Just like (*args, **kwargs) or (...) would be needed on # both #foo and #bar when migrating away from ruby2_keywords. ruby2_keywords def bar(*args) target(*args) end ruby2_keywords def foo(*args) bar(*args) end foo(k: 1)
Cải thiện hiệu suất
YJIT
- Hỗ trợ arm64 / aarch64 trên các nền tảng UNIX.
- Xây dựng YJIT yêu cầu Rust 1.58.1+. [Feature #18481]
Các thay đổi đáng chú ý khác kể từ 3.1
- Hash
- Hash#shift now always returns nil if the hash is empty, instead of returning the default value or calling the default proc. [Bug #16908]
- MatchData
- MatchData#byteoffset has been added. [Feature #13110]
- Module
- Module.used_refinements has been added. [Feature #14332]
- Module#refinements has been added. [Feature #12737]
- Module#const_added has been added. [Feature #17881]
- Proc
- Proc#dup returns an instance of subclass. [Bug #17545]
- Proc#parameters now accepts lambda keyword. [Feature #15357]
- Refinement
- Refinement#refined_class has been added. [Feature #12737]
- RubyVM::AbstractSyntaxTree
- Add
error_tolerantoption forparse,parse_fileandof. [Feature #19013]
- Add
- Set
- Set is now available as a builtin class without the need for
require "set". [Feature #16989] It is currently autoloaded via theSetconstant or a call toEnumerable#to_set.
- Set is now available as a builtin class without the need for
- String
- String#byteindex and String#byterindex have been added. [Feature #13110]
- Update Unicode to Version 14.0.0 and Emoji Version 14.0. [Feature #18037] (also applies to Regexp)
- String#bytesplice has been added. [Feature #18598]
- Struct
- A Struct class can also be initialized with keyword arguments
without
keyword_init: trueonStruct.new[Feature #16806]
- A Struct class can also be initialized with keyword arguments
without
Vấn đề tương thích
Lưu ý: Không bao gồm các bản sửa lỗi tính năng.
Các hằng số đã bị xóa
Các hằng số không dùng nữa sau đã bị xóa.
FixnumandBignum[Feature #12005]Random::DEFAULT[Feature #17351]Struct::GroupStruct::Passwd
Các phương thức đã bị xóa
Các phương thức không dùng nữa sau đã bị xóa.
Dir.exists?[Feature #17391]File.exists?[Feature #17391]Kernel#=~[Feature #15231]Kernel#taint,Kernel#untaint,Kernel#tainted?[Feature #16131]Kernel#trust,Kernel#untrust,Kernel#untrusted?[Feature #16131]
Vấn đề tương thích Stdlib
Psychkhông còn đi kèm mã nguồn libyaml. Người dùng cần tự cài đặt thư viện libyaml qua hệ thống gói. [Feature #18571]
Cập nhật C API
Các C API đã cập nhật
Các API sau đã được cập nhật.
- PRNG update
rb_random_interface_tupdated and versioned. Extension libraries which use this interface and built for older versions. Alsoinit_int32function needs to be defined.
Các C API đã bị xóa
Các API không dùng nữa sau đã bị xóa.
rb_cDatavariable.- “taintedness” and “trustedness” functions. [Feature #16131]
Cập nhật thư viện chuẩn
-
SyntaxSuggest
- Tính năng
syntax_suggesttrước đây làdead_endđã được tích hợp vào Ruby. [Feature #18159]
- Tính năng
-
ErrorHighlight
- Giờ nó chỉ ra (các) đối số của TypeError và ArgumentError
test.rb:2:in `+': nil can't be coerced into Integer (TypeError)
sum = ary[0] + ary[1]
^^^^^^
- Các gem mặc định sau đã được cập nhật.
- RubyGems 3.4.0.dev
- bigdecimal 3.1.2
- bundler 2.4.0.dev
- cgi 0.3.2
- date 3.2.3
- error_highlight 0.4.0
- etc 1.4.0
- io-console 0.5.11
- io-nonblock 0.1.1
- io-wait 0.3.0.pre
- ipaddr 1.2.4
- json 2.6.2
- logger 1.5.1
- net-http 0.2.2
- net-protocol 0.1.3
- ostruct 0.5.5
- psych 5.0.0.dev
- reline 0.3.1
- securerandom 0.2.0
- set 1.0.3
- stringio 3.0.3
- syntax_suggest 0.0.1
- timeout 0.3.0
- Các gem đi kèm sau đã được cập nhật.
- minitest 5.16.3
- net-imap 0.2.3
- rbs 2.6.0
- typeprof 0.21.3
- debug 1.6.2
- Các gem mặc định sau giờ là gem đi kèm.
Xem NEWS hoặc nhật ký commit để biết thêm chi tiết.
Với những thay đổi đó, 2719 tệp đã thay đổi, 191269 thêm(+), 120315 xóa(-) kể từ Ruby 3.1.0!
Tải về
-
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview3.tar.gz
SIZE: 20086542 SHA1: dafca8116d36ceaa32482ab38359768de8c3ae5e SHA256: c041d1488e62730d3a10dbe7cf7a3b3e4268dc867ec20ec991e7d16146640487 SHA512: 860634d95e4b9c48f18d38146dfbdc3c389666d45454248a4ccdfc3a5d3cd0c71c73533aabf359558117de9add1472af228d8eaec989c9336b1a3a6f03f1ae88 -
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview3.tar.xz
SIZE: 14799804 SHA1: c94e2add05502cb5c39afffc995b7c8f000f7df0 SHA256: d3f5619de544240d92a5d03aa289e71bd1103379622c523a0e80ed029a74b3bb SHA512: c1864e2e07c3711eaa17d0f85dfbcc6e0682b077782bb1c155315af45139ae66dc4567c73682d326975b0f472111eb0a70f949811cb54bed0b3a816ed6ac34df -
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview3.zip
SIZE: 24426893 SHA1: 346c051c4be7ab8d0b551fd2ff8169785697db62 SHA256: cf49aa70e7ebd8abebffd5e49cd3bd92e5b9f3782d587cc7ed88c98dd5f17069 SHA512: 4f22b5ea91be17ef5f68cf0acb1e3a226dcc549ad71cc9b40e623220087c4065ca9bea942710f668e5c94ca0323da8d2ccd565f95a9085c1a0e38e9c0543b22f
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 3.2.10
Ruby 3.2.10 đã được phát hành.
Đăng bởi hsbt vào 14 Jan 2026
Phát hành Ruby 4.0.1
Ruby 4.0.1 đã được phát hành.
Đăng bởi k0kubun vào 13 Jan 2026
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