翻译 Ruby Hack Challenge[0x00]: Ruby 的开发文化

kowalskidark · 2021年05月27日 · 最后由 ecnelises 回复于 2021年05月30日 · 389 次阅读

原文:GitHub: ko1/rubyhackchallenge

本文是 MRI 开发者 ko1 为了帮助新手了解 MRI 开发所写的文档

在上手 Ruby 开发时 ko1 向译者推荐了该文档和另外一本 Ruby under a microscope(见文末)

文档中涉及了很多 Ruby C API 的细节,对 Rubyist 开发 C Extension 非常实用

因此我将其英文版本翻译成简体中文,发布在 Ruby China 社区,希望对大家有帮助

(1) MRI 的开发文化介绍

关于这份文档

本文介绍了 MRI 的开发文化。MRI: Matz's Ruby Interpreter(即你使用的 ruby 命令)是开源软件。MRI 的开发始于 1993 年,第一版发布于 1995 年。由于 MRI 是开源的,任何人都可以参与到开发过程中来。但如果你对 MRI 的开发一无所知,参与到其中并不简单。因此,本文为你介绍了我们是如何开发 MRI 的。

本文涵盖了:

  • 如何开发 MRI(开发流程和工具)
  • 如何管理 bug ticket
  • 如何了解 MRI 的内部实现以及如何获取社群信息
  • MRI 中还有哪些待解决的问题

MRI 开发流程

Ruby 是开源软件,因此任何人都能参与开发。

“开发 Ruby” 有两种含义:

  • Ruby 语言的标准(specification)制定。
  • Ruby 的一种实现 —— MRI 的开发。

MRI 是 Ruby 语言的参考实现,因此被 Ruby 标准采纳的功能都将在 MRI 上被实现。 如果我们在 MRI 上修复了一个 bug,意味着我们也会修改 Ruby 标准的对应内容。因此,在决定是否修复 bug 时,必须考虑对兼容性的影响。但准确地说,也存在着许多 MRI 独有的特性,比如 MRI 的虚拟机指令,所以并不是所有对 MRI 的改动都会导致 Ruby 标准产生变化。

代码仓库和 Ruby committer

Ruby 主要的代码仓库使用 Git 进行源码管理 https://www.ruby-lang.org/en/community/ruby-core/ 。许多人都有权修改这个仓库的内容,我们称之为 “Ruby committer”。目前全球大约有 100 位 Ruby committer (实际上活跃的人数要少得多。如果你成为了 “Ruby committer”,你不能放弃这个称号。)

每位 committer 都可以修改 MRI 源码的任意部分,但是不同 committer 都有各自负责的部分。如果一位 committer 想要修改其他部分,他/她需要事先征求负责这部分的 committer 的建议。例如 ko1 是 Ruby 虚拟机的开发者,因此任何一位想要直接修改 Ruby 虚拟机的人在提交改动前都应该征求他的建议。

并不存在正式的 code review 机制。我们会检查被提交的 patch 并指出我们发现的问题。我们使用 git bisect(或类似的技术)来查找问题。如果打算进行大规模的改动,也会请其他的 committer 来 review。

同时,GitHub 上还有一个镜像仓库 https://github.com/ruby/ruby/

Ticket 管理

我们使用 Redmine 这个 bug 追踪工具来讨论对 Ruby 标准的修改、bug report 和其他相关内容。每个被提交的 ticket 对应一个相关的 issue。新的 ticket 和对 ticket 的内容修改会以通知的形式被发送到 Ruby 的邮件列表。这里有英文(ruby-core)和日文(ruby-dev)的邮件列表 https://www.ruby-lang.org/en/community/mailing-lists/

大部分重要的 issue 和 proposal 都用英文提交。 如果是精简的 issue 也可以用日文提交 ticket。

Ticket 可以被分为两类:“Feature request” 和 “Bug report”

  • Feature request
  • Bug reports
    • 奇怪的行为,性能问题等,除了修改 Ruby 标准之外的一切问题。

在你提交 ticket 时会被要求选择用何种语言(英文或日文)进行表述,根据你选择的语言我们会选择将其转发到对应的邮件列表中(ruby-core 或 ruby-dev)。

好的 bug report 应该包含以下几点:

  • 概述(Summary)
  • 可复现的代码和运行环境信息,以便复现 bug(ruby -v 命令的结果,操作系统和编译器的版本信息等)
  • 期望的运行结果
  • 实际的运行结果
  • 如果可能的话,带上一个可以解决此问题的 patch

想要详细了解这部分,请阅读 https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport(英文)或 https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReportJ(日文)。

好的 feature request 应该包含以下几点:

  • 摘要(Abstract)
  • 背景 (Background): 你想要解决什么问题,原因以及你的用例
  • 提案(Proposal)
  • 如果可能,带上你的实现(Implementation)
  • 评估 (Evaluation)
  • 讨论(Discussion)
  • 总结(Summary)

举个例子,如果你想要提交一个 “Feature request”,你很可能会被问到 “你的实际用例是什么?” 用一个极端的例子来解释:如果你提议 “应该修改这个特性,因为它导致了行为的不一致,但是我不再用这个特性了”,那么你的提案将会被拒绝(相较于修复不一致行为,保持兼容性更重要)。

了解更多信息请阅读 https://bugs.ruby-lang.org/projects/ruby/wiki/HowToRequestFeatures.

GitHub 上的 issue 或 pull request 偶尔也会被查看,换句话说, 有时它们也会被忽略。 我建议你去 Redmine 上开一个新的 ticket 链接到你在 GitHub 上创建的 issue 或 pull request。 或者你也可以尝试直接联系一位 Ruby committer。

MRI 的 CI

MRI 是个庞大且复杂的软件,因此使用自动化测试来保证软件质量(QA)非常必要。我们为超过 5000 个文件编写了大约 450,000 行测试。

我们同时准备了大量不同的环境来运行测试。例如,许多广为人知的操作系统如 Linux,macOS,Windows 以及不那么有名的 *BSD,Solaris 等。通常我们使用 Intel 的 x86/64 或 ARM 处理器,但也会用其他平台的处理器进行测试。这是一份 Ruby 支持的平台列表:https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/SupportedPlatforms

因为 MRI 会运行在许多环境中,我们偏向于尽可能地在大量不同环境中进行测试。 使用持续集成(CI)来进行自动化测试是常见的实践方式,Ruby 也不例外。

在使用流行的 Travis-CI 服务之外,我们还维护了 http://rubyci.org 网站来收集更多种环境的测试结果。一般来说 CI 系统会消耗它自身的计算资源。然而我们的资源有限,因此我们并不自己筹备并维护这些环境所需要的计算机,而是交给社区志愿者使用他们自己的计算资源来进行测试,再收集测试结果。chkbuild 工具会构建 Ruby,运行测试,生成测试结果,并对输出进行 diff 以方便我们辨别哪个版本的 Ruby 有何种 bug。

chkbuild 是优秀的测试和 CI 框架,但是由于多种原因(例如,chkbuild 每次都会下载源码)它的运行速度很慢(一般来说要几十分钟)。为了突破这些限制,我们使用另外一个 CI 系统 http://ci.rvm.jp/,它能复用之前的构建并且可以并行地运行构建和测试,将测试需要的时间缩短到了两三分钟。这让我们每天可以进行数百次测试,对发现那些难以复现的 bug(例如时间相关的 bug)非常有帮助。

Ruby committer 应该在他们自己的机器上运行测试。 如果一个 Ruby committer 不小心提交了一份不能通过测试的代码,http://ci.rvm.jp/ 将会检测到错误,不出意外所有 committer 都将会收到警报。

MRI 中待解决的问题

Ruby / MRI 有许多待解决的问题,下面是一些例子:

  • 标准
    • Ruby 2.6, ...
    • Ruby 3
    • JIT 编译(仅为了性能提升?放弃向前兼容?)
    • 静态检查
    • 并发执行
  • 性能
    • 基准测试框架和基准测试
    • 性能提升
  • 文档
  • Bug 修复

以下是我(ko1)想要修复的内部问题:

  • 提升 bytecode serializer 的性能和质量
  • 优化 method dispatch 机制
  • 内联代码
  • 增加 generational GC 支持的对象(特别对于 T_DATA)
  • 提供用于测试主线 gem 的 CI 服务

有关 Ruby 开发的信息

如何探索 MRI 的内部实现

参考文献

英文

如果你想更深层地探索 MRI,你需要掌握 C 语言。

通讯频道

重要提示

本文描述了很多学究式的 “规则”,但是我们解释器开发者最重视的是 “Hacking” 精神。如果你提交了一个非常棒的 patch,即使你没有严格地遵守上述的规则,我们也会支持你的贡献。

Write code, and have fun!

kowalskidark Ruby Hack Challenge[0x01]: MRI 的源码结构 提及了此话题。 05月28日 13:22

《Ruby Under a Microscope》已经有翻译啦

需要 登录 后方可回复, 如果你还没有账号请 注册新账号