原文:GitHub: ko1/rubyhackchallenge
本文是 MRI 开发者 ko1 为了帮助新手了解 MRI 开发所写的文档
在上手 Ruby 开发时 ko1 向译者推荐了该文档和另外一本 Ruby under a microscope(见文末)
文档中涉及了很多 Ruby C API 的细节,对 Rubyist 开发 C Extension 非常实用
因此我将其英文版本翻译成简体中文,发布在 Ruby China 社区,希望对大家有帮助
本文介绍了 MRI 的开发文化。MRI: Matz's Ruby Interpreter(即你使用的 ruby 命令)是开源软件。MRI 的开发始于 1993 年,第一版发布于 1995 年。由于 MRI 是开源的,任何人都可以参与到开发过程中来。但如果你对 MRI 的开发一无所知,参与到其中并不简单。因此,本文为你介绍了我们是如何开发 MRI 的。
本文涵盖了:
Ruby 是开源软件,因此任何人都能参与开发。
“开发 Ruby”有两种含义:
MRI 是 Ruby 语言的参考实现,因此被 Ruby 标准采纳的功能都将在 MRI 上被实现。如果我们在 MRI 上修复了一个 bug,意味着我们也会修改 Ruby 标准的对应内容。因此,在决定是否修复 bug 时,必须考虑对兼容性的影响。但准确地说,也存在着许多 MRI 独有的特性,比如 MRI 的虚拟机指令,所以并不是所有对 MRI 的改动都会导致 Ruby 标准产生变化。
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/。
我们使用 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”
在你提交 ticket 时会被要求选择用何种语言(英文或日文)进行表述,根据你选择的语言我们会选择将其转发到对应的邮件列表中(ruby-core 或 ruby-dev)。
好的 bug report 应该包含以下几点:
想要详细了解这部分,请阅读 https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport (英文)或 https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReportJ(日文)。
好的 feature request 应该包含以下几点:
举个例子,如果你想要提交一个“Feature request”,你很可能会被问到“你的实际用例是什么?” 用一个极端的例子来解释:如果你提议“应该修改这个特性,因为它导致了行为的不一致,但是我不再用这个特性了”,那么你的提案将会被拒绝(相较于修复不一致行为,保持兼容性更重要)。
了解更多信息请阅读 https://bugs.ruby-lang.org/projects/ruby/wiki/HowToRequestFeatures.
GitHub 上的 issue 或 pull request 偶尔也会被查看,换句话说,有时它们也会被忽略。 我建议你去 Redmine 上开一个新的 ticket 链接到你在 GitHub 上创建的 issue 或 pull request。 或者你也可以尝试直接联系一位 Ruby committer。
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 都将会收到警报。
Ruby / MRI 有许多待解决的问题,下面是一些例子:
以下是我(ko1)想要修复的内部问题:
T_DATA
)如果你想更深层地探索 MRI,你需要掌握 C 语言。
本文描述了很多学究式的“规则”,但是我们解释器开发者最重视的是“Hacking”精神。如果你提交了一个非常棒的 patch,即使你没有严格地遵守上述的规则,我们也会支持你的贡献。
Write code, and have fun!