<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>kowalskidark (Kowalski Dark)</title>
    <link>https://ruby-china.org/kowalskidark</link>
    <description>Plugging into a cat</description>
    <language>en-us</language>
    <item>
      <title>Ruby China 社区里全栈工程师的具体定义是什么</title>
      <description>&lt;p&gt;一直都看到社区里很多招聘帖都在发“全栈工程师”的招聘，也有不少培训班说自己是培养“全栈工程师”的。&lt;/p&gt;

&lt;p&gt;个人粗略总结是，要求会写网页前端，也会做网站后端，即“web 前后端都干”。&lt;/p&gt;

&lt;p&gt;请问在 Ruby China 社区这个语言环境下，“全栈“是否有一个可以达成共识的简单定义？&lt;/p&gt;

&lt;p&gt;例如作为基准线的知识（学过什么理论）、技术（已经掌握了什么样的工具）和经验（解决过什么问题）要求。&lt;/p&gt;</description>
      <author>kowalskidark</author>
      <pubDate>Sun, 10 Oct 2021 23:33:23 +0800</pubDate>
      <link>https://ruby-china.org/topics/41752</link>
      <guid>https://ruby-china.org/topics/41752</guid>
    </item>
    <item>
      <title>Ruby Hack Challenge[0x01]: MRI 的源码结构</title>
      <description>&lt;p&gt;&lt;a href="https://ruby-china.org/topics/41305" title=""&gt;Ruby Hack Challenge[0x00]: Ruby 的开发文化&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="(2) MRI 源码结构"&gt;(2) MRI 源码结构&lt;/h2&gt;&lt;h2 id="关于这份文档"&gt;关于这份文档&lt;/h2&gt;
&lt;p&gt;本文介绍了 MRI 的源码结构，同时介绍了 hack MRI 的必要知识。&lt;/p&gt;

&lt;p&gt;包括了以下几个话题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;练习：clone MRI 的源码&lt;/li&gt;
&lt;li&gt;练习：构建 MRI 并安装构建好的二进制&lt;/li&gt;
&lt;li&gt;练习：用构建好的 Ruby 二进制来运行 Ruby 程序&lt;/li&gt;
&lt;li&gt;MRI 源码结构&lt;/li&gt;
&lt;li&gt;练习：初试 hack，修改版本描述信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="前提"&gt;前提&lt;/h2&gt;
&lt;p&gt;要执行以下的命令，我们默认你使用的是 Unix-like 的环境，例如 Linux 和 macOS 等。如果你使用的是 Windows，你需要参考其他的材料。&lt;/p&gt;

&lt;p&gt;备注：我们也提供了一个实验性的 docker 镜像：&lt;code&gt;docker pull koichisasada/rhc&lt;/code&gt;。通过 &lt;code&gt;su rubydev&lt;/code&gt; 命令来切换到 &lt;code&gt;rubydev&lt;/code&gt; 账号开始 hack。&lt;/p&gt;

&lt;p&gt;我们默认使用以下的目录结构：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;workdir/&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ruby/&lt;/code&gt; &amp;lt;- git clone 下来的 ruby 源码目录&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;build/&lt;/code&gt; &amp;lt;- 构建目录（&lt;code&gt;*.o&lt;/code&gt; 文件和其他编译过程产生的文件存储在这里）&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;install/&lt;/code&gt; &amp;lt;- 安装目录（&lt;code&gt;workdir/install/bin/ruby&lt;/code&gt; 是安装好的 Ruby 二进制)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们需要 &lt;code&gt;git&lt;/code&gt;、&lt;code&gt;ruby&lt;/code&gt;、&lt;code&gt;autoconf&lt;/code&gt;、&lt;code&gt;bison&lt;/code&gt;、&lt;code&gt;gcc&lt;/code&gt;（或 &lt;code&gt;clang&lt;/code&gt; 等）和 &lt;code&gt;make&lt;/code&gt; 命令。
如果依赖的库存在，Ruby 标准扩展（例如 zlib、openssl 等）也会被构建。&lt;/p&gt;

&lt;p&gt;如果你用 &lt;code&gt;apt-get&lt;/code&gt;（或 &lt;code&gt;apt&lt;/code&gt;）来做包管理，可以使用下面的命令来安装所有依赖：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get install git ruby autoconf bison gcc make zlib1g-dev libffi-dev libreadline-dev libgdbm-dev libssl-dev
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="练习：Clone MRI 源码"&gt;练习：Clone MRI 源码&lt;/h2&gt;
&lt;p&gt;使用以下命令：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;$ mkdir workdir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ cd workdir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ git clone https://github.com/ruby/ruby.git&lt;/code&gt; # clone 下来的源码将会在 &lt;code&gt;workdir/ruby&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="练习: 构建 MRI 并安装构建好的二进制"&gt;练习：构建 MRI 并安装构建好的二进制&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;确认上文提到过的所需要的命令可用&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ cd workdir/&lt;/code&gt; # 进入 &lt;code&gt;workdir&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ cd ruby&lt;/code&gt; # 进入 &lt;code&gt;workdir/ruby&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ autoconf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ cd ..&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ mkdir build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$ cd build&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ ../ruby/configure --prefix=$PWD/../install --enable-shared&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;prefix&lt;/code&gt; 选项用来指定安装目录，你需要传入一个完整的绝对路径（这里是 &lt;code&gt;workdir/install&lt;/code&gt;）。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Homebrew&lt;/code&gt; 用户需要添加以下选项 &lt;code&gt;--with-openssl-dir="$(brew --prefix openssl)" --with-readline-dir="$(brew --prefix readline)" --disable-libedit&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ make -j&lt;/code&gt; # 执行构建。 &lt;code&gt;-j&lt;/code&gt; 指定了&lt;em&gt;并行构建&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ make install&lt;/code&gt; # 建议：为了加快安装，使用 &lt;code&gt;make install-nodoc&lt;/code&gt; 安装不带 rdoc 的 ruby.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ ../install/bin/ruby -v&lt;/code&gt; 会显示你安装的 ruby 命令的版本信息&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;备注：在执行 &lt;code&gt;make&lt;/code&gt; 时添加 &lt;code&gt;V=1&lt;/code&gt; 选项（例如，&lt;code&gt;make V=1 -j&lt;/code&gt; 等）会输出构建过程中执行的全部命令。默认使用的是 &lt;code&gt;V=0&lt;/code&gt; 即不输出详情。&lt;/p&gt;
&lt;h2 id="练习：用你构建好的 Ruby 来运行 Ruby 程序"&gt;练习：用你构建好的 Ruby 来运行 Ruby 程序&lt;/h2&gt;
&lt;p&gt;你可以通过很多方式，使用构建好的 Ruby 来运行脚本。&lt;/p&gt;

&lt;p&gt;最简单的是直接启动安装好的 Ruby，例如调用 &lt;code&gt;workdir/install/bin/ruby&lt;/code&gt;。这就和调用一个预先构建的 Ruby 二进制一样。但是这意味着每当你修改了 Ruby 的源码，都需要执行一次 &lt;code&gt;make install&lt;/code&gt;，非常费时。&lt;/p&gt;

&lt;p&gt;这里介绍一些便捷的方法，在不安装的前提下启动我们修改过的 Ruby。&lt;/p&gt;
&lt;h3 id="使用 miniruby"&gt;使用 miniruby&lt;/h3&gt;
&lt;p&gt;在构建 Ruby 过后，&lt;code&gt;workdir/build&lt;/code&gt; 下会有一个可用的 &lt;code&gt;miniruby&lt;/code&gt; 命令。&lt;code&gt;miniruby&lt;/code&gt; 是一个精简版的 Ruby，用于构建 Ruby 本身。然而 &lt;code&gt;miniruby&lt;/code&gt; 被精简的部分其实很少：它不能加载扩展库以及缺少完整的字符编码支持。你可以在 &lt;code&gt;miniruby&lt;/code&gt; 中使用大部分的 Ruby 语法。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;miniruby&lt;/code&gt; 是在 Ruby 构建过程中的第一阶段被构建的，因此使用 &lt;code&gt;miniruby&lt;/code&gt; 对 MRI 的改动进行早期验证很有帮助。&lt;/p&gt;

&lt;p&gt;下述开发流程是十分高效的：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;修改 MRI。&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;make miniruby&lt;/code&gt; 来构建 &lt;code&gt;miniruby&lt;/code&gt; (这比 &lt;code&gt;make&lt;/code&gt; 或 &lt;code&gt;make all&lt;/code&gt; 快很多)。&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;miniruby&lt;/code&gt; 执行一段 Ruby 脚本，测试你改动的正确性。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;为了支持这样的开发流程，我们在 Makefile 中提供了一个 &lt;code&gt;make run&lt;/code&gt; 规则，用来：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;构建 &lt;code&gt;miniruby&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;用构建好的 &lt;code&gt;miniruby&lt;/code&gt; 运行 &lt;code&gt;workdir/ruby/test.rb&lt;/code&gt; (&lt;code&gt;test.rb&lt;/code&gt; 是在 Ruby 源码目录里的)。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;借助 &lt;code&gt;make run&lt;/code&gt; 你可以通过以下几步来测试你的改动：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;ruby/test.rb&lt;/code&gt; 为你的改动编写测试。记住在 &lt;code&gt;test.rb&lt;/code&gt; 里你不能 require gems 或者扩展库。&lt;/li&gt;
&lt;li&gt;修改 MRI&lt;/li&gt;
&lt;li&gt;在构建目录里调用 &lt;code&gt;$ make run&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="使用完整功能的 Ruby（而不是 miniruby）"&gt;使用完整功能的 Ruby（而不是 miniruby）&lt;/h3&gt;
&lt;p&gt;如果你想运行“正常的”Ruby，即可以加载扩展库的版本，你可以运行 &lt;code&gt;make runruby&lt;/code&gt;。这样不用执行 &lt;code&gt;make install&lt;/code&gt; 就能运行 Ruby，节省时间。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在 &lt;code&gt;ruby/test.rb&lt;/code&gt; 编写你的测试代码。&lt;/li&gt;
&lt;li&gt;修改 MRI。&lt;/li&gt;
&lt;li&gt;在构建目录里调用 &lt;code&gt;$ make runruby&lt;/code&gt;。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="用 gdb 调试"&gt;用 gdb 调试&lt;/h3&gt;
&lt;p&gt;备注：在 macOS 上运行 &lt;code&gt;gdb&lt;/code&gt; 非常麻烦。我们默认你在 Linux 环境执行下文的指令。&lt;/p&gt;

&lt;p&gt;当你修改 MRI 源码，很容易会引入一些严重问题，导致产生 SEGV。为了调试这种问题，我们提供了一条 Makefile 规则来支持使用 gdb 进行调试，当然你也可以使用断点进行调试。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;在 &lt;code&gt;ruby/test.rb&lt;/code&gt; 编写测试。记住在 &lt;code&gt;test.rb&lt;/code&gt; 里你不能 require gems 或者扩展库。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;调用 &lt;code&gt;$ make gdb&lt;/code&gt;，通过 gdb 启动 miniruby。如果没有问题，gdb 会结束执行而不报错。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;make gdb&lt;/code&gt; 用的是 &lt;code&gt;./miniruby&lt;/code&gt;。如果你想调试 &lt;code&gt;./ruby&lt;/code&gt;, 使用 &lt;code&gt;make gdb-ruby&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;如果你想使用断点，修改 &lt;code&gt;make gdb&lt;/code&gt; 命令产生的 &lt;code&gt;run.gdb&lt;/code&gt; 文件。
例如 &lt;code&gt;b func_name&lt;/code&gt; 这条 gdb 命令会在 &lt;code&gt;func_name&lt;/code&gt; 函数开始的地方插入一个断点。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$ make lldb&lt;/code&gt; 是为 &lt;a href="https://lldb.llvm.org/" rel="nofollow" target="_blank" title=""&gt;lldb&lt;/a&gt; 准备的类似规则，你可以用 lldb 来替代 gdb（但是 Koichi 不清楚细节，因为他并不用 lldb）。如果你用 macOS 这也许有用。&lt;/p&gt;
&lt;h3 id="运行 Ruby 的测试"&gt;运行 Ruby 的测试&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;$ make btest&lt;/code&gt; # 运行 &lt;code&gt;ruby/bootstraptest/&lt;/code&gt; 中的 bootstrap 测试&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ make test-all&lt;/code&gt; # 运行 &lt;code&gt;ruby/test/&lt;/code&gt; 中的 test-unit 测试&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$ make test-spec&lt;/code&gt; # 运行 &lt;code&gt;ruby/spec&lt;/code&gt; 中的测试&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这三种测试有不同的目的和特点。&lt;/p&gt;
&lt;h2 id="MRI 源码结构"&gt;MRI 源码结构&lt;/h2&gt;&lt;h3 id="解释器"&gt;解释器&lt;/h3&gt;
&lt;p&gt;你大致可以看到下述的目录结构：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ruby/*.c&lt;/code&gt; MRI 核心文件

&lt;ul&gt;
&lt;li&gt;Ruby 虚拟机核心

&lt;ul&gt;
&lt;li&gt;Ruby 虚拟机

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vm*.[ch]&lt;/code&gt;: Ruby 虚拟机实现&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vm_core.h&lt;/code&gt;: Ruby 虚拟机数据结构定义&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;insns.def&lt;/code&gt;: Ruby 虚拟机指令定义&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compile.c, iseq.[ch]&lt;/code&gt;: 指令序列 (字节码)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gc.c&lt;/code&gt;: GC 和内存管理&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;thread*.[ch]&lt;/code&gt;: 线程管理&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;variable.c&lt;/code&gt;: 变量管理&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dln*.c&lt;/code&gt;: 扩展库使用的 dll 管理&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;main.c&lt;/code&gt;, &lt;code&gt;ruby.c&lt;/code&gt;: MRI 入口&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;st.c&lt;/code&gt;: Hash 算法实现 (参看 &lt;a href="https://blog.heroku.com/ruby-2-4-features-hashes-integers-rounding" rel="nofollow" target="_blank"&gt;https://blog.heroku.com/ruby-2-4-features-hashes-integers-rounding&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;内置类

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;string.c&lt;/code&gt;: String 类&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;array.c&lt;/code&gt;: Array 类&lt;/li&gt;
&lt;li&gt;... (文件名指明了类名，例如 time.c 对应 Time 类)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/*.h&lt;/code&gt;: 内部定义，C 扩展库不能使用它们。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/include/ruby/*&lt;/code&gt;: 外部定义，C 扩展库可以使用他们。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/enc/&lt;/code&gt;: 字符编码信息。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/defs/&lt;/code&gt;: 各种定义。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/tool/&lt;/code&gt;: 构建 MRI 使用的工具。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/missing/&lt;/code&gt;: 实现了在某些操作系统上缺失的特性。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/cygwin/&lt;/code&gt;, &lt;code&gt;ruby/nacl/&lt;/code&gt;, &lt;code&gt;ruby/win32&lt;/code&gt;, ...: 特定操作系统和运行环境相关的代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="库"&gt;库&lt;/h3&gt;
&lt;p&gt;有两种库：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ruby/lib/&lt;/code&gt;: Ruby 编写的标准库。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/ext/&lt;/code&gt;: C 编写的扩展库，也会被一起打包。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="测试"&gt;测试&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ruby/basictest/&lt;/code&gt;: 旧的测试&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/bootstraptest/&lt;/code&gt;: bootstrap 测试&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/test/&lt;/code&gt;: 用 test-unit 表示的测试&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ruby/spec/&lt;/code&gt;: 用 RSpec 表示的测试&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="杂项"&gt;杂项&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ruby/doc/&lt;/code&gt;, &lt;code&gt;ruby/man/&lt;/code&gt;: 文档&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="Ruby 的构建流程"&gt;Ruby 的构建流程&lt;/h2&gt;
&lt;p&gt;Ruby 的构建流程分为几个阶段，包括了代码生成等。其中有几个工具是用 Ruby 编写的，因此 Ruby 的构建需要依赖 Ruby 解释器。发布的 tarball 包括了生成好的代码，因此用发布的 tarball 安装 Ruby 不需要 Ruby 解释器（以及其他开发工具，比如 bison）。&lt;/p&gt;

&lt;p&gt;如果你想用通过 Subversion 或 Git 仓库获取的源码来构建 MRI，你需要有一个 Ruby 解释器。&lt;/p&gt;

&lt;p&gt;下面描述了构建和安装的流程：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;构建 miniruby

&lt;ol&gt;
&lt;li&gt;parse.y -&amp;gt; parse.c: 用 bison 将语法规则编译成 C 代码。&lt;/li&gt;
&lt;li&gt;insns.def -&amp;gt; vm.inc: 用 ruby（&lt;code&gt;BASERUBY&lt;/code&gt;）将 Ruby 虚拟机指令编译成 C 代码。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.c&lt;/code&gt; -&amp;gt; &lt;code&gt;*.o&lt;/code&gt; (在 Windows 上是 &lt;code&gt;*.obj&lt;/code&gt;): 将 C 代码编译成 object 文件。&lt;/li&gt;
&lt;li&gt;链接 object 文件生成 miniruby&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;构建字符编码支持

&lt;ol&gt;
&lt;li&gt;通过 &lt;code&gt;miniruby&lt;/code&gt; 将 enc/... 翻译成恰当的 C 代码。&lt;/li&gt;
&lt;li&gt;编译 C 代码&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;构建 C 扩展库

&lt;ol&gt;
&lt;li&gt;用 &lt;code&gt;miniruby&lt;/code&gt;，&lt;code&gt;mkmf.rb&lt;/code&gt; 和 &lt;code&gt;extconf.rb&lt;/code&gt; 来生成 &lt;code&gt;Makefile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;用生成的 &lt;code&gt;Makefile&lt;/code&gt; 来执行 &lt;code&gt;make&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;构建 &lt;code&gt;ruby&lt;/code&gt; 命令&lt;/li&gt;
&lt;li&gt;生成文档（&lt;code&gt;rdoc&lt;/code&gt;, &lt;code&gt;ri&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;安装 MRI (安装到 &lt;code&gt;configure --prefix&lt;/code&gt; 选项指定的路径)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;实际的构建过程中步骤会更多，然而要完整地列出所有步骤是非常难的（甚至我也没有记住全部），因此以上的只是精简过的流程。如果你好奇，可以查看包含了所有的规则的 &lt;code&gt;common.mk&lt;/code&gt; 和相关文件。&lt;/p&gt;
&lt;h2 id="练习：初试 hack，修改版本描述信息"&gt;练习：初试 hack，修改版本描述信息&lt;/h2&gt;
&lt;p&gt;让我们开始修改 MRI, 默认我们将所有源码放在 &lt;code&gt;workdir/ruby&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;我们要修改版本描述信息，即 &lt;code&gt;ruby -v&lt;/code&gt;（或 &lt;code&gt;./miniruby -v&lt;/code&gt;）会显示的内容，让它显示你定义的 Ruby 版本信息（例如包含了你名字的版本）。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;在编辑器中打开 &lt;code&gt;version.c&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;大致阅读整个 &lt;code&gt;version.c&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;我们要找的看起来是 &lt;code&gt;ruby_show_version()&lt;/code&gt; 函数&lt;/li&gt;
&lt;li&gt;C 函数 &lt;code&gt;fflush()&lt;/code&gt; 用来输出缓冲区内容，因此我们推测在 &lt;code&gt;fflush()&lt;/code&gt; 前添加用于打印的代码应该有用。&lt;/li&gt;
&lt;li&gt;添加一行 &lt;code&gt;printf("...\n");&lt;/code&gt;（将 &lt;code&gt;...&lt;/code&gt; 替换成你想要的字符串）&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;$ make miniruby&lt;/code&gt; 开始构建（别忘了要先切换到构建目录）&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;$ ./miniruby -v&lt;/code&gt; 并检查结果&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;$ make install&lt;/code&gt; 来安装 Ruby&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;$ ../install/bin/ruby -v&lt;/code&gt;，检查对于安装好的 Ruby 是否生效&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;最后，除了插入 &lt;code&gt;printf(...)&lt;/code&gt; 语句，可以试试替换掉整个 &lt;code&gt;ruby...&lt;/code&gt; 描述（比如换成 &lt;code&gt;perl...&lt;/code&gt;之类的），这会很有趣 ;p&lt;/p&gt;</description>
      <author>kowalskidark</author>
      <pubDate>Fri, 28 May 2021 13:22:13 +0800</pubDate>
      <link>https://ruby-china.org/topics/41309</link>
      <guid>https://ruby-china.org/topics/41309</guid>
    </item>
    <item>
      <title>Ruby Hack Challenge[0x00]: Ruby 的开发文化</title>
      <description>&lt;p&gt;原文：&lt;a href="https://github.com/ko1/rubyhackchallenge" rel="nofollow" target="_blank" title=""&gt;GitHub: ko1/rubyhackchallenge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;本文是 MRI 开发者 ko1 为了帮助新手了解 MRI 开发所写的文档&lt;/p&gt;

&lt;p&gt;在上手 Ruby 开发时 ko1 向译者推荐了该文档和另外一本 Ruby under a microscope（见文末）&lt;/p&gt;

&lt;p&gt;文档中涉及了很多 Ruby C API 的细节，对 Rubyist 开发 C Extension 非常实用&lt;/p&gt;

&lt;p&gt;因此我将其英文版本翻译成简体中文，发布在 Ruby China 社区，希望对大家有帮助&lt;/p&gt;
&lt;h2 id="(1) MRI 的开发文化介绍"&gt;(1) MRI 的开发文化介绍&lt;/h2&gt;&lt;h2 id="关于这份文档"&gt;关于这份文档&lt;/h2&gt;
&lt;p&gt;本文介绍了 MRI 的开发文化。MRI: Matz's Ruby Interpreter（即你使用的 ruby 命令）是开源软件。MRI 的开发始于 1993 年，第一版发布于 1995 年。由于 MRI 是开源的，任何人都可以参与到开发过程中来。但如果你对 MRI 的开发一无所知，参与到其中并不简单。因此，本文为你介绍了我们是如何开发 MRI 的。&lt;/p&gt;

&lt;p&gt;本文涵盖了：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;如何开发 MRI（开发流程和工具）&lt;/li&gt;
&lt;li&gt;如何管理 bug ticket&lt;/li&gt;
&lt;li&gt;如何了解 MRI 的内部实现以及如何获取社群信息&lt;/li&gt;
&lt;li&gt;MRI 中还有哪些待解决的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="MRI 开发流程"&gt;MRI 开发流程&lt;/h2&gt;
&lt;p&gt;Ruby 是开源软件，因此任何人都能参与开发。&lt;/p&gt;

&lt;p&gt;“开发 Ruby”有两种含义：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 语言的标准（specification）制定。&lt;/li&gt;
&lt;li&gt;Ruby 的一种实现 —— MRI 的开发。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MRI 是 Ruby 语言的参考实现，因此被 Ruby 标准采纳的功能都将在 MRI 上被实现。如果我们在 MRI 上修复了一个 bug，意味着我们也会修改 Ruby 标准的对应内容。因此，在决定是否修复 bug 时，必须考虑对兼容性的影响。但准确地说，也存在着许多 MRI 独有的特性，比如 MRI 的虚拟机指令，所以并不是所有对 MRI 的改动都会导致 Ruby 标准产生变化。&lt;/p&gt;
&lt;h3 id="代码仓库和 Ruby committer"&gt;代码仓库和 Ruby committer&lt;/h3&gt;
&lt;p&gt;Ruby 主要的代码仓库使用 Git 进行源码管理 &lt;a href="https://www.ruby-lang.org/en/community/ruby-core/" rel="nofollow" target="_blank"&gt;https://www.ruby-lang.org/en/community/ruby-core/&lt;/a&gt; 。许多人都有权修改这个仓库的内容，我们称之为“Ruby committer”。目前全球大约有 100 位 Ruby committer (实际上活跃的人数要少得多。如果你成为了“Ruby committer”，你不能放弃这个称号。）&lt;/p&gt;

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

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

&lt;p&gt;同时，GitHub 上还有一个镜像仓库 &lt;a href="https://github.com/ruby/ruby/" rel="nofollow" target="_blank"&gt;https://github.com/ruby/ruby/&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="Ticket 管理"&gt;Ticket 管理&lt;/h2&gt;
&lt;p&gt;我们使用 &lt;a href="https://bugs.ruby-lang.org/issues/" rel="nofollow" target="_blank" title=""&gt;Redmine&lt;/a&gt; 这个 bug 追踪工具来讨论对 Ruby 标准的修改、bug report 和其他相关内容。每个被提交的 ticket 对应一个相关的 issue。新的 ticket 和对 ticket 的内容修改会以通知的形式被发送到 Ruby 的邮件列表。这里有英文（ruby-core）和日文（ruby-dev）的邮件列表 &lt;a href="https://www.ruby-lang.org/en/community/mailing-lists/" rel="nofollow" target="_blank"&gt;https://www.ruby-lang.org/en/community/mailing-lists/&lt;/a&gt;。&lt;/p&gt;

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

&lt;p&gt;Ticket 可以被分为两类：“Feature request”和“Bug report”&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature request

&lt;ul&gt;
&lt;li&gt;请求为 Ruby 语言本身添加新特性或修改已有特性&lt;/li&gt;
&lt;li&gt;顺带一提，Redmine 的 URL &lt;a href="https://bugs.ruby-lang.org/projects/ruby-trunk/" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby-trunk/&lt;/a&gt; 里有“bugs”这个词 :)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bug reports

&lt;ul&gt;
&lt;li&gt;奇怪的行为，性能问题等，除了修改 Ruby 标准之外的一切问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;在你提交 ticket 时会被要求选择用何种语言（英文或日文）进行表述，根据你选择的语言我们会选择将其转发到对应的邮件列表中（ruby-core 或 ruby-dev）。&lt;/p&gt;

&lt;p&gt;好的 bug report 应该包含以下几点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;概述（Summary）&lt;/li&gt;
&lt;li&gt;可复现的代码和运行环境信息，以便复现 bug（ruby -v 命令的结果，操作系统和编译器的版本信息等）&lt;/li&gt;
&lt;li&gt;期望的运行结果&lt;/li&gt;
&lt;li&gt;实际的运行结果&lt;/li&gt;
&lt;li&gt;如果可能的话，带上一个可以解决此问题的 patch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;想要详细了解这部分，请阅读 &lt;a href="https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReport&lt;/a&gt; （英文）或 &lt;a href="https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReportJ" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby/wiki/HowToReportJ&lt;/a&gt;（日文）。&lt;/p&gt;

&lt;p&gt;好的 feature request 应该包含以下几点：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;摘要（Abstract）&lt;/li&gt;
&lt;li&gt;背景 (Background): 你想要解决什么问题，原因以及你的用例&lt;/li&gt;
&lt;li&gt;提案（Proposal）&lt;/li&gt;
&lt;li&gt;如果可能，带上你的实现（Implementation）&lt;/li&gt;
&lt;li&gt;评估 (Evaluation)&lt;/li&gt;
&lt;li&gt;讨论（Discussion）&lt;/li&gt;
&lt;li&gt;总结（Summary）&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;了解更多信息请阅读 &lt;a href="https://bugs.ruby-lang.org/projects/ruby/wiki/HowToRequestFeatures" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby/wiki/HowToRequestFeatures&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;GitHub 上的 issue 或 pull request 偶尔也会被查看，换句话说，有时它们也会被忽略。
我建议你去 Redmine 上开一个新的 ticket 链接到你在 GitHub 上创建的 issue 或 pull request。
或者你也可以尝试直接联系一位 Ruby committer。&lt;/p&gt;
&lt;h2 id="MRI 的 CI"&gt;MRI 的 CI&lt;/h2&gt;
&lt;p&gt;MRI 是个庞大且复杂的软件，因此使用自动化测试来保证软件质量（QA）非常必要。我们为超过 5000 个文件编写了大约 450,000 行测试。&lt;/p&gt;

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

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

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

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

&lt;p&gt;Ruby committer 应该在他们自己的机器上运行测试。
如果一个 Ruby committer 不小心提交了一份不能通过测试的代码，&lt;a href="http://ci.rvm.jp/" rel="nofollow" target="_blank"&gt;http://ci.rvm.jp/&lt;/a&gt; 将会检测到错误，不出意外所有 committer 都将会收到警报。&lt;/p&gt;
&lt;h2 id="MRI 中待解决的问题"&gt;MRI 中待解决的问题&lt;/h2&gt;
&lt;p&gt;Ruby / MRI 有许多待解决的问题，下面是一些例子：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;标准

&lt;ul&gt;
&lt;li&gt;Ruby 2.6, ...&lt;/li&gt;
&lt;li&gt;Ruby 3&lt;/li&gt;
&lt;li&gt;JIT 编译（仅为了性能提升？放弃向前兼容？）&lt;/li&gt;
&lt;li&gt;静态检查&lt;/li&gt;
&lt;li&gt;并发执行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;性能

&lt;ul&gt;
&lt;li&gt;基准测试框架和基准测试&lt;/li&gt;
&lt;li&gt;性能提升&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;文档&lt;/li&gt;
&lt;li&gt;Bug 修复&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;以下是我（ko1）想要修复的内部问题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;提升 bytecode serializer 的性能和质量&lt;/li&gt;
&lt;li&gt;优化 method dispatch 机制&lt;/li&gt;
&lt;li&gt;内联代码&lt;/li&gt;
&lt;li&gt;增加 generational GC 支持的对象（特别对于 &lt;code&gt;T_DATA&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;提供用于测试主线 gem 的 CI 服务&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="有关 Ruby 开发的信息"&gt;有关 Ruby 开发的信息&lt;/h2&gt;&lt;h3 id="如何探索 MRI 的内部实现"&gt;如何探索 MRI 的内部实现&lt;/h3&gt;&lt;h4 id="参考文献"&gt;参考文献&lt;/h4&gt;&lt;h5 id="英文"&gt;英文&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Redmine wiki

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bugs.ruby-lang.org/projects/ruby/wiki" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby/wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ruby-hacking-guide.github.io/" rel="nofollow" target="_blank" title=""&gt;Ruby Hacking Guide&lt;/a&gt; by &lt;a href="/minero-aoki" class="user-mention" title="@minero-aoki"&gt;&lt;i&gt;@&lt;/i&gt;minero-aoki&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 1.8 时代 MRI 内部实现的完整教程。&lt;/li&gt;
&lt;li&gt;Part 1, 2 (GC, Parser) 仍很有价值。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://patshaughnessy.net/ruby-under-a-microscope" rel="nofollow" target="_blank" title=""&gt;Ruby Under a Microscope&lt;/a&gt; by Pat Shaughnessy

&lt;ul&gt;
&lt;li&gt;Ruby 2.0 MRI 内部实现的简单教程。&lt;/li&gt;
&lt;li&gt;不完整，但对于新手了解 MRI 内部实现很有帮助。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://rubybib.org/" rel="nofollow" target="_blank" title=""&gt;The Ruby Bibliography&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果你想更深层地探索 MRI，你需要掌握 C 语言。&lt;/p&gt;
&lt;h3 id="通讯频道"&gt;通讯频道&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ruby's Redmine: &lt;a href="https://bugs.ruby-lang.org/projects/ruby/" rel="nofollow" target="_blank"&gt;https://bugs.ruby-lang.org/projects/ruby/&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Ticket&lt;/li&gt;
&lt;li&gt;Wiki&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;邮件列表

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.ruby-lang.org/en/community/mailing-lists/" rel="nofollow" target="_blank"&gt;https://www.ruby-lang.org/en/community/mailing-lists/&lt;/a&gt; (英文) &lt;a href="https://www.ruby-lang.org/ja/community/mailing-lists/" rel="nofollow" target="_blank"&gt;https://www.ruby-lang.org/ja/community/mailing-lists/&lt;/a&gt; (日文)&lt;/li&gt;
&lt;li&gt;ruby-core (英文)&lt;/li&gt;
&lt;li&gt;ruby-dev (日文)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;会议

&lt;ul&gt;
&lt;li&gt;RubyConf 和其他会议&lt;/li&gt;
&lt;li&gt;日本国内

&lt;ul&gt;
&lt;li&gt;RubyKaigi&lt;/li&gt;
&lt;li&gt;RegionalRubyKaigi&lt;/li&gt;
&lt;li&gt;Asakusa.rb, *.rb&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ruby 开发者会议 (每月在东京举行)&lt;/li&gt;
&lt;li&gt;联系开发者个人

&lt;ul&gt;
&lt;li&gt;Twitter

&lt;ul&gt;
&lt;li&gt;&lt;a href="/yukihiro_matz" class="user-mention" title="@yukihiro_matz"&gt;&lt;i&gt;@&lt;/i&gt;yukihiro_matz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Gitter &lt;a href="https://gitter.im/ruby/ruby" rel="nofollow" target="_blank"&gt;https://gitter.im/ruby/ruby&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="重要提示"&gt;重要提示&lt;/h2&gt;
&lt;p&gt;本文描述了很多学究式的“规则”，但是我们解释器开发者最重视的是“Hacking”精神。如果你提交了一个非常棒的 patch，即使你没有严格地遵守上述的规则，我们也会支持你的贡献。&lt;/p&gt;

&lt;p&gt;Write code, and have fun!&lt;/p&gt;</description>
      <author>kowalskidark</author>
      <pubDate>Thu, 27 May 2021 15:44:58 +0800</pubDate>
      <link>https://ruby-china.org/topics/41305</link>
      <guid>https://ruby-china.org/topics/41305</guid>
    </item>
    <item>
      <title>大家有没有留意过 Kernel::require 这个 API 的性能问题</title>
      <description>&lt;p&gt;完整的 benchmark 代码在 &lt;a href="https://github.com/DarkKowalski/ruby-require-perf" rel="nofollow" target="_blank" title=""&gt;ruby-require-perf&lt;/a&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                        user     system      total        real
require(relative)   0.001705   0.003376   0.005081 (  0.005089)
require(absolute)   0.001190   0.000009   0.001199 (  0.001195)
require_relative    0.002576   0.000000   0.002576 (  0.002567)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Kernel::require&lt;/code&gt; 在传入一个相对路径的时候比绝对路径要慢了差不多 4 ~5 倍，比 &lt;code&gt;Kernel::require_relative&lt;/code&gt; 慢了 2 倍&lt;/p&gt;

&lt;p&gt;想知道平时大家在写代码的时候有留意过这个问题吗？&lt;/p&gt;

&lt;p&gt;另外这个 &lt;code&gt;Kernel::require&lt;/code&gt; API 性能优化的提案在今年的 GSoC Ruby 立项了，也许我们最后能在 &lt;a href="https://github.com/ko1" rel="nofollow" target="_blank" title=""&gt;ko1&lt;/a&gt; 的帮助下调查出来结果&lt;/p&gt;</description>
      <author>kowalskidark</author>
      <pubDate>Thu, 20 May 2021 14:41:45 +0800</pubDate>
      <link>https://ruby-china.org/topics/41289</link>
      <guid>https://ruby-china.org/topics/41289</guid>
    </item>
  </channel>
</rss>
