Ruby 3.0.0 RC1 发布

我们很高兴地宣布 Ruby 3.0.0-rc1 版本的发布。

它引入了许多新功能和性能改进。

静态分析

RBS

RBS 是一种描述 Ruby 程序类型的语言。

包括 TypeProf 在内的类型检查器和其他支持 RBS 的工具将通过 RBS 定义更好地理解 Ruby 程序。

您可以写下类和模块的定义:类中定义的方法、实例变量及其类型以及继承/混入关系。

RBS 的目标是支持 Ruby 程序中常见的模式,它允许编写高级类型,包括联合类型、方法重载和泛型。它还支持具有接口类型的鸭子类型。

Ruby 3.0 附带 rbs gem,它允许解析和处理用 RBS 编写的类型定义。以下是带有类、模块和常量定义的 RBS 的一个小例子。

module ChatApp
  VERSION: String
  class Channel
    attr_reader name: String
    attr_reader messages: Array[Message]
    attr_reader users: Array[User | Bot]              # `|` means union types, `User` or `Bot`.
    def initialize: (String) -> void
    def post: (String, from: User | Bot) -> Message   # Method overloading is supported.
            | (File, from: User | Bot) -> Message
  end
end

有关详细信息,请参阅 rbs gem 的 README

TypeProf

TypeProf 是 Ruby 包中捆绑的类型分析工具。

目前,TypeProf 用作一种类型推断。

它读取纯(未类型注释)的 Ruby 代码,分析定义了哪些方法以及如何使用它们,并生成 RBS 格式的类型签名的原型。

这是一个 TypeProf 的简单演示。

一个示例输入

# test.rb
class User
  def initialize(name:, age:)
    @name, @age = name, age
  end
  attr_reader :name, :age
end
User.new(name: "John", age: 20)

一个示例输出

$ typeprof test.rb
# Classes
class User
  attr_reader name : String
  attr_reader age : Integer
  def initialize : (name: String, age: Integer) -> [String, Integer]
end

您可以通过将输入保存为“test.rb”并调用名为“typeprof test.rb”的命令来运行 TypeProf。

您还可以在线尝试 TypeProf。(它在服务器端运行 TypeProf,所以如果出现故障,请见谅!)

有关详细信息,请参阅文档演示

TypeProf 是实验性的,尚未完全成熟;仅支持 Ruby 语言的一个子集,并且类型错误的检测是有限的。但它仍在快速发展,以提高语言特性的覆盖率、分析性能和可用性。欢迎任何反馈。

Ractor(实验性)

Ractor 是一种类似 Actor 模型的并发抽象,旨在提供并行执行功能,而无需担心线程安全问题。

您可以创建多个 ractors,并且可以并行运行它们。Ractor 使您能够创建线程安全的并行程序,因为 ractors 不能共享普通对象。ractors 之间的通信由消息传递支持。

为了限制对象的共享,Ractor 对 Ruby 的语法引入了一些限制(如果没有多个 Ractors,则没有限制)。

规范和实现尚未成熟,将来可能会更改,因此此功能被标记为实验性,并在第一次 Ractor.new 时显示“实验性功能”警告。

以下小程序使用两个 ractors 并行计算 n.prime?n 是一个相对较大的整数)。您将确认在并行计算机上,程序执行速度比串行程序快大约 x2 倍。

require 'prime'
# n.prime? with sent integers in r1, r2 run in parallel
r1, r2 = *(1..2).map do
  Ractor.new do
    n = Ractor.receive
    n.prime?
  end
end
# send parameters
r1.send 2**61 - 1
r2.send 2**61 + 15
# wait for the results of expr1, expr2
p r1.take #=> true
p r2.take #=> true

有关更多详细信息,请参阅 doc/ractor.md

Fiber 调度器

引入 Fiber#scheduler 来拦截阻塞操作。这允许在不更改现有代码的情况下实现轻量级并发。观看 “不要等我,Ruby 3 的可扩展并发”,了解其工作原理概述。

当前支持的类/方法

  • Mutex#lockMutex#unlockMutex#sleep
  • ConditionVariable#wait
  • Queue#popSizedQueue#push
  • Thread#join
  • Kernel#sleep
  • Process.wait
  • IO#waitIO#readIO#write 和相关方法(例如,#wait_readable#gets#puts 等)。
  • 不支持 IO#select

(用链接解释 Async gem)。此示例程序将同时执行多个 HTTP 请求

(解释这个:)

  1. async 是外部 gem
  2. async 使用这个新功能
require 'async'
require 'net/http'
require 'uri'
Async do
  ["ruby", "python", "c"].each do |topic|
    Async do
      Net::HTTP.get(URI "https://www.google.com/search?q=#{topic}")
    end
  end
end

其他值得注意的新功能

  • 重新设计了单行模式匹配。(实验性)

    • 添加了 =>。它可以像向右赋值一样使用。

      0 => a
      p a #=> 0
      
      {b: 0, c: 1} => {b:}
      p b #=> 0
      
    • in 被更改为返回 truefalse

      # version 3.0
      0 in 1 #=> false
      
      # version 2.7
      0 in 1 #=> raise NoMatchingPatternError
      
  • 添加了查找模式。(实验性)

    case ["a", 1, "b", "c", 2, "d", "e", "f", 3]
    in [*pre, String => x, String => y, *post]
      p pre  #=> ["a", 1]
      p x    #=> "b"
      p y    #=> "c"
      p post #=> [2, "d", "e", "f", 3]
    end
    
  • 添加了无尽方法定义。

    def square(x) = x * x
    
  • Hash#except 现在是内置的。

    h = { a: 1, b: 2, c: 3 }
    p h.except(:a) #=> {:b=>2, :c=>3}
    
  • 内存视图作为实验性功能添加

    • 这是一组新的 C-API,用于在扩展库之间交换原始内存区域,例如数字数组和位图图像。扩展库还可以共享内存区域的元数据,包括形状、元素格式等等。使用这些类型的元数据,扩展库甚至可以适当地共享多维数组。此功能是通过参考 Python 的缓冲区协议设计的。

性能改进

  • MJIT 中实现了许多改进。详见 NEWS。
  • 将长代码粘贴到 IRB 的速度比 Ruby 2.7.0 捆绑的速度快 53 倍。例如,粘贴此示例代码所需的时间从 11.7 秒缩短到 0.22 秒。

自 2.7 以来的其他值得注意的更改

  • 关键字参数与其他参数分离。
    • 原则上,在 Ruby 2.7 上打印警告的代码将无法工作。有关详细信息,请参阅文档
    • 顺便说一下,参数转发现在支持前导参数。

      def method_missing(meth, ...)
        send(:"do_#{ meth }", ...)
      end
      
  • 模式匹配(case/in)不再是实验性的。
  • $SAFE 功能已完全删除;现在它是一个普通的全局变量。
  • 回溯的顺序在 Ruby 2.5 中被反转,现在又恢复了。现在它的行为类似于 Ruby 2.4;首先打印错误消息和发生异常的行号,然后打印其调用者。
  • 一些标准库已更新。
    • RubyGems 3.2.2
    • Bundler 2.2.2
    • IRB 1.2.6
    • Reline 0.1.5
    • Psych 3.2.1
    • JSON 2.4.1
    • BigDecimal 3.0.0
    • CSV 3.1.9
    • Digest 3.0.0
    • Fiddle 1.0.4
    • StringIO 3.0.0
    • StringScanner 3.0.0
  • 以下库不再是捆绑的 gem。安装相应的 gem 以使用这些功能。
    • net-telnet
    • xmlrpc
  • 以下默认 gem 现在是捆绑的 gem。
    • rexml
    • rss
  • 以下 stdlib 文件现在是默认 gem,并在 rubygems.org 上发布。
    • English
    • abbrev
    • base64
    • drb
    • debug
    • erb
    • find
    • net-ftp
    • net-http
    • net-imap
    • net-protocol
    • open-uri
    • optparse
    • pp
    • prettyprint
    • resolv-replace
    • resolv
    • rinda
    • set
    • securerandom
    • shellwords
    • tempfile
    • tmpdir
    • time
    • tsort
    • un
    • weakref
    • digest
    • io-nonblock
    • io-wait
    • nkf
    • pathname
    • syslog
    • win32ole

有关更多详细信息,请参阅 NEWS提交日志

经过这些更改,自 Ruby 2.7.0 以来,3889 个文件已更改,195560 次插入 (+),152740 次删除 (-)

请尝试 Ruby 3.0.0-rc1,并给我们任何反馈!

下载

  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.tar.gz

    SIZE: 19488885
    SHA1: 34ede2128a90ef3217d9cab9efcdf20fc444f67c
    SHA256: e1270f38b969ce7b124f0a4c217e33eda643f75c7cb20debc62c17535406e37f
    SHA512: 798926db82d27366b39be97556ac5cb322986b96df913c398449bd3ece533e484a3047fe35e7a6241dfbd0f7da803438f5b04b805b33f95c73e3e41d0bb51183
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.tar.xz

    SIZE: 14341128
    SHA1: deff34cf67373dca166e9961051b6c4723aaaec6
    SHA256: f1adda082f9291e394d25ed32975abbef90962dc4c8b11130586a0151558e79a
    SHA512: f4f13dbfa1c96088eb3dbfba0cb1fe99f4e17197ee2d4b78fbe16496780797a10daa3f2ff9c38d2d7b316974101eccf45184708ad05491fb49898b3a7cc6d673
    
  • https://cache.ruby-lang.org/pub/ruby/3.0/ruby-3.0.0-rc1.zip

    SIZE: 23902334
    SHA1: e3e20b4d0ec895e579ae416f2b7552c6be3596f7
    SHA256: 25ced95fa544af6a64d348dc5eace008edfda22f55ed1f6ad9f932b344e6196d
    SHA512: c81b3bf7ce582bf39fd7bc1e691d0777ed4cf38ca6b4d54bc9edaef076ae8bcecb6a86ebfd773591f7d8533e772517033c762d35fdc8b05cb4db4488c2bacec2
    

什么是 Ruby

Ruby 最初由 Matz(松本行弘)于 1993 年开发,现在作为开源项目进行开发。它在多个平台上运行,并在世界各地使用,尤其是在 Web 开发中。