由 naruse 发表于 2022-09-09
翻译: GAO Jun
我们很高兴地宣布 Ruby 3.2.0-preview2。Ruby 3.2 增加了很多新功能和性能改进。
基于 WASI 的 WebAssembly 支持
这是首次基于 WASI 的 WebAssembly 支持。使得 CRuby 二进制内容可用于浏览器、Serverless Edge、以及其他 WebAssembly/WASI 嵌入环境。目前,此功能已通过除 Thread API 之外的 basic 和 bootstrap 测试套件。
背景
WebAssembly (Wasm) 希望能够在浏览器中提供安全快速的运行程序的方式。但其目标,也就是在不同环境中安全高效的运行程序,不仅是 web 应用长期以来的目标,也是其他一般程序所需要的。
WASI (The WebAssembly System Interface) 被设计用于此类应用场景。尽管此类应用需要与操作系统进行通信,WebAssembly 却运行在一个没有系统接口的虚拟机之上。WASI 使之标准化。
基于这些项目,Ruby 的 WebAssembly/WASI 支持能使 Ruby 开发者可以编写能运行于兼容此类功能的平台上。
应用场景
此功能使得开发人员可以在 WebAssembly 环境中使用 CRuby。一个此类应用场景的案例是 TryRuby playground 的 CRuby 支持。现在您可以在您的浏览器中尝试原生的 CRuby。
技术要点
目前,WASI 和 WebAssembly 仍在不断演进,同时基于安全原因,还缺少一些功能来实现纤程、异常和垃圾回收。 所以,CRuby 使用了一种可以控制用户空间中执行的二进制转换技术 Asyncify 来填补这一鸿沟。
此外,我们创建了 WASI 之上的虚拟文件系统,于是就可以很容易地将 Ruby 应用打包成单个 .wasm 文件,进而简化分发 Ruby 应用的过程。
相关链接
Regexp 超时设置
新增正则表达式匹配的超时设置。
Regexp.timeout = 1.0
/^a*b?a*$/ =~ "a" * 50000 + "x"
#=> 1秒后 Regexp::TimeoutError
众所周知,正则表达式匹配的耗时可能出乎意料的长。如果您的代码尝试从一个不可信输入中匹配一个低效的正则表达式,攻击者可以借此发起有效的拒绝服务攻击(所谓的正则表达式 DoS,或 ReDoS)。
根据您的 Ruby 程序的需要,可以通过设置 Regexp.timeout
来避免或减轻这种 DoS 风险。请在您的程序中进行尝试,我们欢迎您的反馈。
请注意,Regexp.timeout
是全局性的配置。如果您希望对于某些特殊的正则表达式使用不同的超时设置,您可以使用 Regexp.new
中的 timeout
关键词。
Regexp.timeout = 1.0
# 这个 Regexp 没有超时设置
long_time_re = Regexp.new("^a*b?a*$", timeout: nil)
long_time_re =~ "a" * 50000 + "x" # 不会被中断
最初提议: https://bugs.ruby-lang.org/issues/17837
其他值得注意的新功能
不再捆绑第三方源代码
-
我们不再捆绑第三方源代码,例如
libyaml
,libffi
。-
psych 中已经移除了 libyaml 的代码。您可能需要在 Ubuntu/Debian 平台中安装
libyaml-dev
。软件包的名称可能因平台不同而各异。 -
在 preview2 中,
fiddle
将移除 libffi。
-
语言
-
除了在方法参数中使用,匿名的可变长参数现在可以作为参数进行传递 [Feature #18351]
def foo(*) bar(*) end def baz(**) quux(**) end
-
接受一个单独位置参数的 proc 不再会自动解封装。 [Bug #18633]
proc{|a, **k| a}.call([1, 2]) # Ruby 3.1 及之前版本 # => 1 # Ruby 3.2 及之后版本 # => [1, 2]
-
对于显示对象的常量赋值求值顺序,将始终使用单属性赋值求值顺序。参考下面的代码:
foo::BAR = baz
foo
现在在baz
之前求值。类似的,对于多重常量的赋值,使用从左到右的求值顺序。参考下面的代码:foo1::BAR1, foo2::BAR2 = baz1, baz2
现在使用下面的求值顺序:
foo1
foo2
baz1
baz2
-
查找模式不再是实验性功能。 [Feature #18585]
-
使用可变长参数 (例如
*args
) 的方法,如果同时希望通过foo(*args)
使用关键词参数的,那么必须使用ruby2_keywords
进行标记。也就是说,所有希望通过*args
来使用关键字参数的方法现在毫无例外地都必须使用ruby2_keywords
进行标记。一旦某个库需要 Ruby 3+,这将是一个更容易的过渡升级方式。此前,当接收方法使用*args
时,ruby2_keywords
标记被保留,但这可能是错误并且是行为不一致的。对于查找潜在缺失的ruby2_keywords
的好方法应当是运行测试套件,检查测试失败时调用的最后一个方法,这个方法必须接收关键词参数。通过在错误处使用puts nil, caller, nil
,然后检查在调用链上的每一个使用自动委派关键词的方法/块被标记为ruby2_keywords
。 [Bug #18625] [Bug #16466]def target(**kw) end # Ruby 2.7-3.1 可以意外地在没有 ruby2_keywords 的情况下执行,在 3.2 中必需。 # 如需去除 ruby2_keywords,需要修改 #foo 和 #bar 的参数为 (*args, **kwargs) 或 (...)。 ruby2_keywords def bar(*args) target(*args) end ruby2_keywords def foo(*args) bar(*args) end foo(k: 1)
性能改进
YJIT
- 在 UNIX 平台中支持 arm64 / aarch64。
- 编译 YJIT 需要 Rust 1.58.1+. [Feature #18481]
自 3.1 以来其他值得注意的变更
- Hash
- 当 hash 为空时,Hash#shift 现在总是返回 nil,此前行为是返回默认值或调用默认 proc。 [Bug #16908]
- MatchData
- 新增 MatchData#byteoffset 。 [Feature #13110]
- Module
- 新增 Module.used_refinements 。 [Feature #14332]
- 新增 Module#refinements 。 [Feature #12737]
- 新增 Module#const_added 。 [Feature #17881]
- Proc
- Proc#dup 返回子类的一个实例。 [Bug #17545]
- Proc#parameters 现在接受 lambda 关键字。 [Feature #15357]
- Refinement
- 新增 Refinement#refined_class 。 [Feature #12737]
- Set
- Set 现在可以直接使用,不需要调用
require "set"
。 [Feature #16989] 目前其通过Set
常量或对Enumerable#to_set
调用自动载入。
- Set 现在可以直接使用,不需要调用
- String
- 新增 String#byteindex 和 String#byterindex 。 [Feature #13110]
- 更新 Unicode 至 Version 14.0.0,Emoji Version 14.0. [Feature #18037] (同样适用于 Regexp)
- 新增 String#bytesplice 。 [Feature #18598]
- Struct
- 即使在
Struct.new
中不设置keyword_init: true
,Struct 类也可以通过关键词参数进行初始化。 [Feature #16806]
- 即使在
兼容性问题
注意:不包含特性的问题修正
被移除的常量
下列废弃常量被移除。
Fixnum
与Bignum
[Feature #12005]Random::DEFAULT
[Feature #17351]Struct::Group
Struct::Passwd
被移除的方法
下列废弃方法被移除。
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]
标准库兼容性问题
Psych
不再捆绑 libyaml 源代码 用户需要自行通过包管理系统安装 libyaml 库。[Feature #18571]
C API 更新
被移除的 C API
下列废弃的 API 被移除。
- 变量
rb_cData
。 - “taintedness” 与 “trustedness” 函数。 [Feature #16131]
标准库更新
-
下列默认 gems 被更新。
- 待定
-
下列 bundled gems 被更新。
- 待定
-
下列默认 gems 现在是 bundled gems。您需要在 bundler 环境中,将其加入
Gemfile
文件。- 待定
自 Ruby 3.1.0 以来,伴随这些变更, 2393 个文件被更改, 新增 168931 行(+),删除 113411 行(-)!
下载
-
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview2.tar.gz
SIZE: 19816780 SHA1: 2106c77fc1600daf41ae137ecc4cf7937e27f67f SHA256: 8a78fd7a221b86032f96f25c1d852954c94d193b9d21388a9b434e160b7ed891 SHA512: 5e9ddcb1a43cff449b0062cc716bfb80a9ebbb14a1b063f34005e2998c2c5033badb44e882232db9b2fceda9376f6615986e983511fda2575d60894752b605cc
-
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview2.tar.xz
SIZE: 14578112 SHA1: 538b3ea4dc0d99f60f8bd6f71e65a56ceeb41c18 SHA256: 01fac0929dccdabc0686c1109da6c187897a401da9ff8851242befa92f7fd430 SHA512: 0f4cc919284fdfa1a42b6381760d1b3a4660da4b0fcdd2adf01ea04a425548b3c5ac090866915675db73964a1055090e54dd97cf4628cbb69403e541c71c28ff
-
https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.0-preview2.zip
SIZE: 24150109 SHA1: 69ffffc52cad626166f73f21f25c29c9d73fe0e8 SHA256: 67f9ad3110be1975b3ce547c0a6e2c910dfc1945fd6e9bb1bd340568897c6554 SHA512: 1447e099e7a8da0ff206fda6f4e466640d6e86e9da8148315ab0154684b1fd22c02c0022b5a2f4d3fc00103b4e8cef8e35a770174921fd8c6abeca9ad41c1818
Ruby是什么
Ruby 最初由 Matz (松本行弘,Yukihiro Matsumoto) 于 1993 年开发,现在以开源软件的形式开发。它可以在多个平台上运行,并在全球得到广泛使用,尤其是Web开发领域。