<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>gazeldx (leader.me 张健)</title>
    <link>https://ruby-china.org/gazeldx</link>
    <description>leader.me - 打造程序员个人IP</description>
    <language>en-us</language>
    <item>
      <title>注册域名的 Rubyist 注意了！</title>
      <description>&lt;p&gt;我两周前收到 Name cheap 的邮件，说我的帐户被&lt;strong&gt;永久封禁&lt;/strong&gt;了。原因是我是&lt;strong&gt;中国人&lt;/strong&gt;。
如果想解除封禁，需要提供&lt;strong&gt;在非制裁国家居住的证明&lt;/strong&gt;。
之间我已经按他们的要求，提供了我的护照照片，但这依然不够！&lt;/p&gt;

&lt;p&gt;原文如下:
Please let us remind you that it is also required to provide us with proof of residence in a non-sanctioned country, such as a lease agreement or utility bill. You can attach this document to this email as a scan or photocopy.&lt;/p&gt;

&lt;p&gt;译文如下：
请注意，您还需要提供在非制裁国家居住的证明，例如租赁协议或水电费账单。您可以将此文件以扫描件或复印件的形式作为附件添加到此邮件中。&lt;/p&gt;

&lt;p&gt;花了 $700 买的域名就这么没了，更别提我的业务无法在这些 Premium 域名上开展了。要拿回这些域名，看来我得出个国，并签一份租房合同 &lt;img title=":grimacing:" alt="😬" src="https://twemoji.ruby-china.com/2/svg/1f62c.svg" class="twemoji"&gt; &lt;/p&gt;

&lt;p&gt;2026-01-12 更新：经过交涉，现在我的帐号已经恢复可用。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Fri, 09 Jan 2026 12:33:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/44442</link>
      <guid>https://ruby-china.org/topics/44442</guid>
    </item>
    <item>
      <title>leader.me：程序员的“数字名片”，一站式打造个人品牌</title>
      <description>&lt;h3 id="为什么开发 leader.me?"&gt;为什么开发 leader.me?&lt;/h3&gt;
&lt;p&gt;2024 年 5 月，我失业了。半年都没找到工作。我反思，用人单位为什么不雇佣我？最后发现，我居然没有拿得出手的作品！其实我做过几个成功的项目，但那时候，我没有把这些成功的项目进行截图，以至于&lt;strong&gt;这些项目因故下线后，无法把项目的成功分享给雇主&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;因此，我开始刻意地打造自己的&lt;strong&gt;作品集&lt;/strong&gt;。
花了六个月时间，完成了 &lt;a href="https://leetcode.blog" rel="nofollow" target="_blank" title=""&gt;LT 算法网&lt;/a&gt; 和 &lt;a href="https://github.com/is-bio/is-bio" rel="nofollow" target="_blank" title=""&gt;开源 Markdown/Git 博客&lt;/a&gt;，把自己包装成算法高手和开源热心人士。果然，在 2025 年 6 月，我成功入职上海的一家上市公司，做资深 Ruby 开发工程师。&lt;/p&gt;

&lt;p&gt;考虑到程序员们在这个就业压力变大的季节，也有同样想向雇主展示自己作品集的需求，我开发了 &lt;a href="https://www.leader.me" rel="nofollow" target="_blank" title=""&gt;leader.me&lt;/a&gt;，还包括&lt;strong&gt;简历、博客&lt;/strong&gt;等功能，助力程序员打造线上个人 IP。&lt;/p&gt;
&lt;h3 id="中国程序员的烦恼"&gt;中国程序员的烦恼&lt;/h3&gt;
&lt;p&gt;作为中国程序员，你是否还在为个人作品散落、简历无人问津、博客维护费时费力而烦恼？&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;传统方式如 WordPress，需要自己折腾服务器、主题、SEO，成本高（域名 + 主机每年几百元），内容输出慢；自搭博客更惨，技术债堆积，更新一次像打仗。&lt;/li&gt;
&lt;li&gt;Medium 等平台成为会员才能绑定独立域名，会员费高昂。&lt;/li&gt;
&lt;li&gt;招聘平台如 LinkedIn？它强在人脉和职位推送，但你的代码仓库、项目细节、深度文章往往被简化成“简历附件”，难以凸显技术深度，品牌感弱。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;leader.me&lt;/strong&gt; 来了——专为开发者设计的 SaaS 平台，定位“专业开发者身份构建”，让你像 GitHub Pages 一样简单，却更精致、更品牌化。&lt;/p&gt;

&lt;p&gt;核心功能一应俱全：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;作品集&lt;/strong&gt;（上传项目截图、代码链接，一键展示技术栈）；&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;简历&lt;/strong&gt;（动态生成 PDF/网页版，支持实时更新）；&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;博客&lt;/strong&gt;（Markdown 编辑，内置代码高亮，SEO 友好）；&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这些全集成在一页内，无需多站点跳转，用户一看就懂你的实力。&lt;/p&gt;

&lt;p&gt;对比传统博客，leader.me 零代码部署、自动优化，省时 90%；对比 LinkedIn，它不只是“求职工具”，而是你的“个人官网”，突出作品驱动的品牌，吸引猎头主动找上门。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;价格亲民&lt;/strong&gt;：核心服务起步低（具体详见官网），远低于自搭成本。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;提供高端子域名（如 yourname.leader.me），瞬间提升专业范儿；&lt;/li&gt;
&lt;li&gt;支持&lt;strong&gt;自定义域名绑定&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这些小功能，大大放大你的在线影响力。&lt;/p&gt;

&lt;p&gt;总之，leader.me 不是博客或招聘站，而是你的“开发者名片”——低成本、高效率，专注品牌输出。别再让作品埋没，赶紧试试 &lt;a href="https://www.leader.me" rel="nofollow" target="_blank" title=""&gt;leader.me&lt;/a&gt;，10 分钟建站，开启被动收入机会！（官网：&lt;a href="https://www.leader.me" rel="nofollow" target="_blank" title=""&gt;www.leader.me&lt;/a&gt;）&lt;/p&gt;
&lt;h3 id="感恩回馈 Ruby-China 社区的用户"&gt;感恩回馈 Ruby-China 社区的用户&lt;/h3&gt;
&lt;p&gt;作为社区的老粉丝，能给到大家的，就是实打实的省钱：&lt;strong&gt;冲多少，送多少&lt;/strong&gt;，2025 年 12 月 31 日截止！&lt;/p&gt;

&lt;p&gt;与多年优惠叠加后，最低只需要 &lt;strong&gt;$3&lt;/strong&gt; 就可以使用 1 年的 leader.me 产品！&lt;/p&gt;
&lt;h3 id="leader.me 开发团队"&gt;leader.me 开发团队&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;架构师：张健&lt;/li&gt;
&lt;li&gt;主程：&lt;a href="https://clacky.ai" rel="nofollow" target="_blank" title=""&gt;Clacky.ai&lt;/a&gt;。Clacky.ai 虽然宣称对小白用户友好，实际上，对程序员更友好，&lt;strong&gt;对 Ruby 程序员最友好&lt;/strong&gt;！因为 Clacky.ai 专注主打 Rails 编程，让 Clacky.ai 开发功能时，我的经验是把大的功能模块拆小，给 Clacky.ai 明确的指导，Clacky.ai 基本上能一次搞定。不要让 AI 一个指令开发许多东西，以免代码失控。&lt;/li&gt;
&lt;li&gt;辅程：Gemini, 张健&lt;/li&gt;
&lt;li&gt;产品经理：张健，Grok, Gemini&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>gazeldx</author>
      <pubDate>Fri, 12 Dec 2025 12:12:01 +0800</pubDate>
      <link>https://ruby-china.org/topics/44416</link>
      <guid>https://ruby-china.org/topics/44416</guid>
    </item>
    <item>
      <title>今天开源一个博客引擎，助您使用 Markdown 和 Git 进行博客写作</title>
      <description>&lt;h2 id="使用 "&gt;使用 "Markdown" 和 "Git" 享受博客写作。一个基于 Ruby on Rails 8 的开源个人博客引擎。&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub 仓库地址：&lt;a href="https://github.com/is-bio/is-bio" rel="nofollow" target="_blank" title=""&gt;is-bio&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;演示网站：&lt;a href="https://zhangjian.dev" rel="nofollow" target="_blank" title=""&gt;张健的博客&lt;/a&gt; 和 &lt;a href="https://stopgaming.org" rel="nofollow" target="_blank" title=""&gt;Stop Gaming&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="如何在本地使用 Markdown 文件撰写文章，并通过 git push 发布？"&gt;如何在本地使用 Markdown 文件撰写文章，并通过 &lt;code&gt;git push&lt;/code&gt; 发布？&lt;/h2&gt;
&lt;p&gt;目前，&lt;a href="https://jekyllrb.com/" rel="nofollow" target="_blank" title=""&gt;Jekyll&lt;/a&gt; 或 &lt;a href="https://gohugo.io/" rel="nofollow" target="_blank" title=""&gt;Hugo&lt;/a&gt; 已经可以满足上述要求，但并不完美。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;is-bio&lt;/strong&gt; 也可以满足上述要求，但有几点不同。&lt;/p&gt;
&lt;h2 id="is-bio 在哪些方面比 Jekyll 或 Hugo 更好？"&gt;
&lt;em&gt;is-bio&lt;/em&gt; 在哪些方面比 Jekyll 或 Hugo &lt;strong&gt;更好&lt;/strong&gt;？&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Jekyll 或 Hugo 生成的博客文章是&lt;em&gt;静态&lt;/em&gt;的，而 &lt;em&gt;is-bio&lt;/em&gt; 是一个&lt;strong&gt;动态&lt;/strong&gt;博客引擎。

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;静态&lt;/em&gt;博客的功能非常有限。&lt;/li&gt;
&lt;li&gt;在&lt;em&gt;动态&lt;/em&gt;博客 &lt;em&gt;is-bio&lt;/em&gt; 中，目前已集成电子邮件订阅功能，未来还将支持简历、作品集、评论、点赞、阅读次数、在线支付等功能。&lt;/li&gt;
&lt;li&gt;此外，您还可以为您的博客&lt;strong&gt;添加一些自定义功能&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;您可能会说，如果我不会用 Ruby 编程怎么办？

&lt;ul&gt;
&lt;li&gt;两年前，这会是个问题，但现在，我们有了 AI，您可以&lt;strong&gt;让 AI 帮助您实现一些小功能&lt;/strong&gt;！&lt;/li&gt;
&lt;li&gt;如果出现错误，告诉 AI 并让 AI 纠正它。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;对于不熟悉 Jekyll 或 Hugo 的人来说，即使是找到一个好看的主题也很&lt;strong&gt;困难&lt;/strong&gt;。

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;is-bio&lt;/em&gt; 目前支持一个&lt;strong&gt;漂亮的免费主题&lt;/strong&gt;，未来还会添加更多主题。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Jekyll 或 Hugo 的文档长达很多页。谁能在一页内解释清楚所有内容？

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;is-bio&lt;/em&gt; 可以。有关如何使用 &lt;em&gt;is-bio&lt;/em&gt; 方法通过 &lt;em&gt;Markdown&lt;/em&gt; 和 &lt;em&gt;Git&lt;/em&gt; 发布帖子的信息，请阅读 &lt;a href="https://github.com/is-bio/markdown-blog" rel="nofollow" target="_blank" title=""&gt;markdown-blog&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;一篇博客文章可以翻译成多种语言并在博客上显示。这个功能目前还没有任何博客引擎支持。然而，&lt;em&gt;is-bio&lt;/em&gt; 已经支持了，让您的文章能够触达全球用户。&lt;/li&gt;
&lt;li&gt;对于建立个人品牌来说，仅有一个博客是不够的。最好有简历和作品集。事实上，博客并不是最重要的功能，&lt;strong&gt;简历和作品集才是&lt;/strong&gt;。在下一个版本中，我们将推出简历功能。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="使用 is-bio 的成本是多少？"&gt;使用 &lt;em&gt;is-bio&lt;/em&gt; 的成本是多少？&lt;/h2&gt;
&lt;p&gt;许多程序员已经在使用服务器，通常，该服务器并未得到充分利用。&lt;/p&gt;

&lt;p&gt;您可以在此服务器上安装 &lt;em&gt;is-bio&lt;/em&gt;，而无需担心端口 &lt;code&gt;80/443&lt;/code&gt; 被另一个网站占用。在安装文档中，我已经指出了如何完美解决这个实际不存在的问题。&lt;/p&gt;

&lt;p&gt;因此，您的成本增加可能是&lt;strong&gt;$2/月&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="为什么开发者不再经常写博客了？"&gt;为什么开发者不再经常写博客了？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在使用 &lt;a href="https://pages.github.com/" rel="nofollow" target="_blank" title=""&gt;GitHub Pages&lt;/a&gt;（基于 Jekyll）后，他们&lt;strong&gt;很少&lt;/strong&gt;写博客了。为什么？&lt;/li&gt;
&lt;li&gt;在我看来，普通的博客系统&lt;strong&gt;无法再为博主创造太多价值&lt;/strong&gt;！那些博客并非旨在为博主带来价值。&lt;/li&gt;
&lt;li&gt;以我自己为例，我的 GitHub Pages 的 &lt;a href="https://gazeldx.github.io/" rel="nofollow" target="_blank" title=""&gt;张健的旧博客&lt;/a&gt; 一点也不吸引人，所以我无法兴奋地写作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="is-bio：一个专注于为开发者带来价值的博客引擎"&gt;is-bio：一个专注于为开发者带来价值的博客引擎&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;您可以看到 &lt;a href="https://zhangjian.dev" rel="nofollow" target="_blank" title=""&gt;张健的新博客&lt;/a&gt;（基于 &lt;em&gt;is-bio&lt;/em&gt;）设计精良。&lt;/li&gt;
&lt;li&gt;我开始期望客户&lt;strong&gt;直接在我的博客上为我的服务付费&lt;/strong&gt;！&lt;/li&gt;
&lt;li&gt;通过博客，我向潜在客户传达了一个信息：我是 Web 开发、算法和戒断游戏成瘾方面的专家！&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="在服务器上部署 is-bio"&gt;在服务器上部署 is-bio&lt;/h2&gt;
&lt;p&gt;如果您想在服务器上部署 &lt;em&gt;is-bio&lt;/em&gt;，请阅读 &lt;a href="https://github.com/is-bio/is-bio/blob/main/docs/deploy/deploy_on_CentOS10_zh.md" rel="nofollow" target="_blank" title=""&gt;deploy_on_CentOS10.md&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="在本地计算机上安装 is-bio"&gt;在本地计算机上安装 is-bio&lt;/h2&gt;
&lt;p&gt;以下内容主要针对在 &lt;em&gt;macOS&lt;/em&gt; 本地进行安装。对于其他操作系统，安装过程类似。&lt;/p&gt;
&lt;h2 id="安装 Ruby"&gt;安装 Ruby&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;is-bio&lt;/em&gt; 是基于 Ruby 3.3.x 版本开发的，但其他版本应该也可以工作。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;如果您是临时用户并且不经常使用 Ruby，请使用 Homebrew 安装 Ruby。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;ruby
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ruby 开发者使用 Ruby 版本管理器来安装 Ruby。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/rbenv/ruby-build" rel="nofollow" target="_blank" title=""&gt;ruby-build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/postmodern/ruby-install" rel="nofollow" target="_blank" title=""&gt;ruby-install&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/asdf-vm/asdf" rel="nofollow" target="_blank" title=""&gt;asdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="克隆 'is-bio' 项目并安装 Ruby gems"&gt;克隆 'is-bio' 项目并安装 Ruby gems&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/is-bio/is-bio.git
&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/is-bio
bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="设置credentials"&gt;设置 credentials&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/is-bio
&lt;span class="c"&gt;# 此文件包含所有需要设置的credentials。&lt;/span&gt;
&lt;span class="nb"&gt;cat &lt;/span&gt;config/credentials.yml.example &lt;span class="c"&gt;# 使用下一个命令设置"所有"credentials：&lt;/span&gt;
&lt;span class="c"&gt;# 保存后，将创建 "config/credentials.yml.enc" 和 "config/master.key"。&lt;/span&gt;
&lt;span class="c"&gt;# 为了使修改后的credentials生效，您需要重新启动 Rails Web 服务器。&lt;/span&gt;
&lt;span class="nv"&gt;EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"vim"&lt;/span&gt; bin/rails credentials:edit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;config/credentials.yml.example&lt;/code&gt; 中显示的所有项目都需要设置！&lt;/p&gt;

&lt;p&gt;如果您仍然不确定如何设置某些项目，可以先使用 &lt;code&gt;config/credentials.yml.example&lt;/code&gt; 中的默认值，然后在发现相关功能不起作用时，根据相关说明正确设置值。&lt;/p&gt;
&lt;h2 id="准备 SQLite 数据库"&gt;准备 SQLite 数据库&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/is-bio
rails db:migrate &lt;span class="c"&gt;# 数据库文件是 `./storage/development.sqlite3`。运行它没有副作用。&lt;/span&gt;
rails db:seed &lt;span class="c"&gt;# 运行它没有副作用。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="安装主题"&gt;安装主题&lt;/h2&gt;
&lt;p&gt;阅读 &lt;a href="https://github.com/is-bio/is-bio/blob/main/docs/install_theme.md" rel="nofollow" target="_blank" title=""&gt;docs/install_theme.md&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="启动 Rails Web 服务器"&gt;启动 Rails Web 服务器&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/is-bio
rails assets:precompile &lt;span class="c"&gt;# 每当任何资源发生更改时都需要执行此操作。运行它没有副作用。&lt;/span&gt;
rails s &lt;span class="c"&gt;# 启动 Rails Web 服务器。&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;访问 &lt;a href="http://localhost:3000/" rel="nofollow" target="_blank"&gt;http://localhost:3000/&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id="创建管理员用户"&gt;创建管理员用户&lt;/h3&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/is-bio
vim db/seeds.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;取消注释代码的前几行以创建管理员用户。&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rails db:seed
git restore db/seeds.rb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用此电子邮件地址和密码登录 &lt;a href="http://localhost:3000/admin" rel="nofollow" target="_blank"&gt;http://localhost:3000/admin&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="通过 SMTP 发送电子邮件"&gt;通过 SMTP 发送电子邮件&lt;/h2&gt;
&lt;p&gt;请按照 &lt;a href="https://github.com/PersonalBranding/is-bio/blob/main/docs/send_email_via_smtp_guide.md" rel="nofollow" target="_blank" title=""&gt;docs/send_email_via_smtp_guide.md&lt;/a&gt; 中的说明完成此步骤。&lt;/p&gt;
&lt;h2 id="启动 "&gt;启动 "Solid Queue" 处理后台任务&lt;/h2&gt;
&lt;p&gt;博客文章、图片、文件同步、发送电子邮件、生成缩略图等都需要启动后台任务！&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/is-bio
&lt;span class="nb"&gt;rm &lt;/span&gt;public/assets/.manifest.json
rails assets:precompile &lt;span class="c"&gt;# 您需要重新启动 Rails Web 服务器才能使更改生效。&lt;/span&gt;
bin/jobs &lt;span class="c"&gt;# 启动它&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;首先，使用电子邮件地址和密码登录 &lt;a href="http://localhost:3000/admin" rel="nofollow" target="_blank"&gt;http://localhost:3000/admin&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;其次，使用此用户名和密码登录 &lt;a href="http://localhost:3000/jobs" rel="nofollow" target="_blank"&gt;http://localhost:3000/jobs&lt;/a&gt; 查看是否有失败的任务。

&lt;ul&gt;
&lt;li&gt;用户名和密码可以通过运行 &lt;code&gt;EDITOR="vim" bin/rails credentials:edit&lt;/code&gt; 获取。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="创建并安装您的 "&gt;创建并安装您的 "GitHub App" 以将本地 "markdown-blog" 仓库的文件更改同步到博客网站&lt;/h2&gt;
&lt;p&gt;在这里，博客网站是您的本地 Rails Web 服务器。如果您 &lt;a href="https://github.com/PersonalBranding/is-bio/blob/main/docs/deploy/deploy_on_CentOS10_zh.md" rel="nofollow" target="_blank" title=""&gt;deploy_on_CentOS10.md&lt;/a&gt;，博客网站是您的真实 Web 服务器。&lt;/p&gt;

&lt;p&gt;如果您不熟悉如何使用 &lt;em&gt;Markdown&lt;/em&gt; 和 &lt;em&gt;Git&lt;/em&gt; 发布博客，请阅读 &lt;a href="https://github.com/PersonalBranding/markdown-blog" rel="nofollow" target="_blank" title=""&gt;markdown-blog&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;请按照 &lt;a href="https://github.com/PersonalBranding/is-bio/blob/main/docs/GitHub_App.md" rel="nofollow" target="_blank" title=""&gt;GitHub_App.md&lt;/a&gt; 中的说明完成此步骤。&lt;/p&gt;
&lt;h3 id="其它功能：自动生成图片缩略图"&gt;其它功能：自动生成图片缩略图&lt;/h3&gt;
&lt;p&gt;欢迎大家提出批评和改进意见。简历和作品集功能还在开发中。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Sat, 19 Apr 2025 10:39:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/44141</link>
      <guid>https://ruby-china.org/topics/44141</guid>
    </item>
    <item>
      <title>Clacky AI 和 Cursor AI 用 Ruby 语言做力扣题解的对比</title>
      <description>&lt;p&gt;两个 AI 编程工具 Clacky AI 和 Cursor AI，用了同样的提示词，没有修改任何设置，随机选四道题目，要求它们参考我写的其它语言的题解，写出 Ruby 版本的题解。大家欣赏下，看看喜欢哪个。&lt;/p&gt;
&lt;h2 id="力扣题一"&gt;力扣题一&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://leetcode.blog/zh/leetcode/28-find-the-index-of-the-first-occurrence-in-a-string" rel="nofollow" target="_blank"&gt;https://leetcode.blog/zh/leetcode/28-find-the-index-of-the-first-occurrence-in-a-string&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clacky AI 给出的实现代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# @param {String} haystack&lt;/span&gt;
&lt;span class="c1"&gt;# @param {String} needle&lt;/span&gt;
&lt;span class="c1"&gt;# @return {Integer}&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;str_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Cursor AI 给出的实现代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;str_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;本题结论：: Clacky AI 胜出。因为用&lt;code&gt;.each&lt;/code&gt;了，符合 Ruby 风格。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="力扣题二"&gt;力扣题二&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://leetcode.blog/zh/leetcode/160-intersection-of-two-linked-lists" rel="nofollow" target="_blank"&gt;https://leetcode.blog/zh/leetcode/160-intersection-of-two-linked-lists&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clacky AI 给出的实现代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Definition for singly-linked list.&lt;/span&gt;
&lt;span class="c1"&gt;# class ListNode&lt;/span&gt;
&lt;span class="c1"&gt;#     attr_accessor :val, :next&lt;/span&gt;
&lt;span class="c1"&gt;#     def initialize(val)&lt;/span&gt;
&lt;span class="c1"&gt;#         @val = val&lt;/span&gt;
&lt;span class="c1"&gt;#         @next = nil&lt;/span&gt;
&lt;span class="c1"&gt;#     end&lt;/span&gt;
&lt;span class="c1"&gt;# end&lt;/span&gt;

&lt;span class="c1"&gt;# @param {ListNode} head_a&lt;/span&gt;
&lt;span class="c1"&gt;# @param {ListNode} head_b&lt;/span&gt;
&lt;span class="c1"&gt;# @return {ListNode}&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_intersection_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head_a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;head_b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;node_count_a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;node_count_b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head_a&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;
        &lt;span class="n"&gt;node_count_a&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head_b&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;
        &lt;span class="n"&gt;node_count_b&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head_a&lt;/span&gt;
    &lt;span class="n"&gt;smaller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head_b&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;node_count_b&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;node_count_a&lt;/span&gt;
        &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head_b&lt;/span&gt;
        &lt;span class="n"&gt;smaller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head_a&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node_count_b&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;node_count_a&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;smaller&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;smaller&lt;/span&gt;

        &lt;span class="n"&gt;bigger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bigger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;
        &lt;span class="n"&gt;smaller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;smaller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Cursor AI 给出的实现代码，与 Clacky AI 相同，仅有两处不同：&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;一，注释部分不同。Cursor AI 以下内容没有。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# @param {ListNode} head_a&lt;/span&gt;
&lt;span class="c1"&gt;# @param {ListNode} head_b&lt;/span&gt;
&lt;span class="c1"&gt;# @return {ListNode}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而没有是符合预期的，Clacky AI 总是创造性地加上参数和返回值注释。&lt;/p&gt;

&lt;p&gt;二，Indents 不同，Clacky AI 用了 4 个空格做 Indents，这个不符合 Ruby 风格。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;本题结论：平手，Clacky AI 略下风。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="力扣题三"&gt;力扣题三&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://leetcode.blog/zh/leetcode/383-ransom-note" rel="nofollow" target="_blank"&gt;https://leetcode.blog/zh/leetcode/383-ransom-note&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clacky AI 给出的实现代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;can_construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ransom_note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;magazine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;char_to_count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;magazine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_char&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;char_to_count&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;ransom_note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_char&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;char_to_count&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;char_to_count&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;(这里，我开始提醒 Clacky AI 要用 indents 2。希望下次会改正，果然，下一题改正了)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cursor AI 给出的代码完全相同，但 indents 为 2，这是好的。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;本题结论：平手。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="力扣题四"&gt;力扣题四&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://leetcode.blog/zh/leetcode/59-spiral-matrix-ii" rel="nofollow" target="_blank"&gt;https://leetcode.blog/zh/leetcode/59-spiral-matrix-ii&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clacky AI 给出的实现代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="vi"&gt;@increments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="vi"&gt;@increment_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
      &lt;span class="vi"&gt;@matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
      &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="vi"&gt;@matrix&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@increments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@increment_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;next_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;next_j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;next_i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;next_i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="vi"&gt;@matrix.size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
       &lt;span class="n"&gt;next_j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;next_j&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="vi"&gt;@matrix.size&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; 
       &lt;span class="vi"&gt;@matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;next_i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;next_j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="vi"&gt;@increment_index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="vi"&gt;@increment_index&lt;/span&gt; &lt;span class="o"&gt;%=&lt;/span&gt; &lt;span class="vi"&gt;@increments.size&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="vi"&gt;@increments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@increment_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Cursor AI 给出的实现代码：&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
    &lt;span class="vi"&gt;@increments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
    &lt;span class="vi"&gt;@increment_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
      &lt;span class="vi"&gt;@matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;
      &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="vi"&gt;@matrix&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@increments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@increment_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="vi"&gt;@matrix.length&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
       &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="vi"&gt;@matrix.length&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
       &lt;span class="vi"&gt;@matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="vi"&gt;@increment_index&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
      &lt;span class="vi"&gt;@increment_index&lt;/span&gt; &lt;span class="o"&gt;%=&lt;/span&gt; &lt;span class="vi"&gt;@increments.length&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="vi"&gt;@increments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="vi"&gt;@increment_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;区别：Cursor AI 把实例变量定义在 &lt;code&gt;initialize&lt;/code&gt; 方法中，这导致多写了两行代码，另外还多写了一次 &lt;code&gt;@matrix = nil&lt;/code&gt;，这个不符合我的刷题喜好。&lt;/p&gt;

&lt;p&gt;Clacky AI 定义了 local variables &lt;code&gt;next_i&lt;/code&gt;和&lt;code&gt;next_j&lt;/code&gt;，这是不符合我的预期的，因为我给出其它语言的例子了。但这个创造感觉还是不错的，可读性提高了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;本题结论：Clacky AI 胜出。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;另外，Clacky AI 每一个题解都少输出了一行三个上斜点，后来我提醒它，它最后改正了。&lt;/p&gt;
&lt;h2 id="最终结论"&gt;最终结论&lt;/h2&gt;
&lt;p&gt;本次测试，我发现 Clacky AI 创造性可能更强一点，比如我之前预期是用变量名 &lt;code&gt;charactor&lt;/code&gt;的，它认为不好，改成了&lt;code&gt;c&lt;/code&gt;了。&lt;/p&gt;

&lt;p&gt;Cursor AI 更按部就班一点，因为我明确地告诉他们，依照我手写的其它语言的例子去做，但 Clacky AI 还是会进行再创造，不过几次再创造我愿意接纳了。&lt;/p&gt;

&lt;p&gt;最终，我将选择 Clacky AI 写的题解，当然，依然是我的题解，因为逻辑上我要求它们参考我手写的其它语言的例子。&lt;/p&gt;

&lt;p&gt;欢迎评论。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Tue, 25 Mar 2025 17:05:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/44107</link>
      <guid>https://ruby-china.org/topics/44107</guid>
    </item>
    <item>
      <title>Ruby-China 可以安装成一个 App. 但缺少了一个浏览器的后退功能。不太方便。</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/gazeldx/42c621d6-b6e0-4b4f-a9d6-68df923a5f74.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/gazeldx/50e32080-312f-40b1-9259-e31ef6f123cb.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Tue, 04 Jul 2023 17:59:30 +0800</pubDate>
      <link>https://ruby-china.org/topics/43206</link>
      <guid>https://ruby-china.org/topics/43206</guid>
    </item>
    <item>
      <title>Best way for Python and Java to reverse a string</title>
      <description>&lt;h2 id="Python"&gt;Python&lt;/h2&gt;
&lt;p&gt;According to &lt;a href="https://stackoverflow.com/questions/931092/reverse-a-string-in-python" rel="nofollow" target="_blank" title=""&gt;reverse-a-string-in-python&lt;/a&gt;, the solution would be&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;hello world&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;[::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make it more readable, I have to define a function:&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;target_string&lt;/span&gt;&lt;span class="p"&gt;[::&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Java"&gt;Java&lt;/h2&gt;
&lt;p&gt;According to &lt;a href="https://stackoverflow.com/questions/7569335/reverse-a-string-in-java" rel="nofollow" target="_blank" title=""&gt;reverse-a-string-in-java&lt;/a&gt;, the solution would be&lt;/p&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;reverse&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I think for Python, there should be a method called &lt;code&gt;reverse()&lt;/code&gt; to let me use it like &lt;code&gt;'hello world'.reverse()&lt;/code&gt;.
&lt;img title=":grinning:" alt="😀" src="https://twemoji.ruby-china.com/2/svg/1f600.svg" class="twemoji"&gt; &lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Fri, 04 Mar 2022 16:51:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/42181</link>
      <guid>https://ruby-china.org/topics/42181</guid>
    </item>
    <item>
      <title>How to use Hotwire Turbo in your Rails 6 project with Webpacker.</title>
      <description>&lt;h2 id="Background"&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://turbo.hotwired.dev/handbook/introduction" rel="nofollow" target="_blank" title=""&gt;Turbo&lt;/a&gt; can help refresh only a part of our webpage and don't need to refresh the whole page.&lt;/p&gt;

&lt;p&gt;If we build a Single Page App or traditional web, we can do this by Ajax with json and JavaScript.&lt;/p&gt;

&lt;p&gt;Now we have &lt;code&gt;Turbo&lt;/code&gt; and don't need to write Ajax, json or JavaScript to make it.&lt;/p&gt;

&lt;p&gt;After you have finished this tutorial, you will see that &lt;strong&gt;your Rails app works like a SPA&lt;/strong&gt;. Cool. Isn't it.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Turbolinks&lt;/code&gt; is the old name of Turbo.&lt;/p&gt;

&lt;p&gt;From &lt;a href="https://github.com/hotwired/turbo-rails" rel="nofollow" target="_blank"&gt;https://github.com/hotwired/turbo-rails&lt;/a&gt; , we can see the &lt;a href="https://hotwired.dev/#screencast" rel="nofollow" target="_blank" title=""&gt;official example video&lt;/a&gt; is represented with an assets pipeline example, not with Webpacker.&lt;/p&gt;
&lt;h2 id="Goal"&gt;Goal&lt;/h2&gt;
&lt;p&gt;Here I will let you know how to integrate &lt;code&gt;Turbo&lt;/code&gt; with Webpacker and Bootstrap 5.&lt;/p&gt;

&lt;p&gt;Imagine that we have a navigation bar with some links. Each of those links maps to a Rails route.
We hope that when we click those links, the navigation itself, the header and the footer not to be refreshed.&lt;/p&gt;
&lt;h2 id="Steps"&gt;Steps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Create a Rails 6 project (the default is using webpacker).&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;gem 'turbo-rails'&lt;/code&gt; to and remove &lt;code&gt;gem 'turbolinks'&lt;/code&gt; from &lt;code&gt;Gemfile&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;bundle install&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;rails turbo:install&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;yarn add @hotwired/turbo-rails&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Find a file (like: &lt;code&gt;frontend.js&lt;/code&gt;) under &lt;code&gt;app/javascript/packs/&lt;/code&gt; and add &lt;code&gt;import "@hotwired/turbo-rails"&lt;/code&gt; to the first line.
Then remove &lt;code&gt;import Turbolinks from "turbolinks"&lt;/code&gt; and &lt;code&gt;Turbolinks.start()&lt;/code&gt; from this file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also in this file, add these code to make the frame have a blue border:&lt;/p&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;turbo-frame&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;In the file &lt;code&gt;app/views/layouts/application.html.erb&lt;/code&gt;, add these:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;csrf_meta_tags&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;csp_meta_tag&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;javascript_pack_tag&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;stylesheet_pack_tag&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;data-turbo-frame=&lt;/span&gt;&lt;span class="s"&gt;"main_frame"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;%= products_path %&amp;gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Product List &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;data-turbo-frame=&lt;/span&gt;&lt;span class="s"&gt;"main_frame"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"&amp;lt;%= cdrs_path %&amp;gt;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;CDR List &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;turbo-frame&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"main_frame"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;yield&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/turbo-frame&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;app/controllers/products_controller.rb&lt;/code&gt;, write this:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProductsController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;BaseController&lt;/span&gt;
  &lt;span class="c1"&gt;# Remember to comment out this line like this. Just don't use a layout specifically. If you write a layout specifically, the layout will always be used!&lt;/span&gt;
  &lt;span class="c1"&gt;# Also don't use `layout false`, otherwise when user open the url in a new browser tab, the default layout `application` was lost.&lt;/span&gt;
  &lt;span class="c1"&gt;# In the end, you will have only one layout for the `Turbo` usage, that is the `app/views/layouts/application.html.erb`. And you need never specifically write `layout 'application'`. &lt;/span&gt;
  &lt;span class="c1"&gt;# That is OK and good enough because you can dynamically generate the content of this `application.html.erb`.&lt;/span&gt;
  &lt;span class="c1"&gt;# You can have other `logouts` for other pages which don't use `Turbo` like `sign_in` or `register` pages.&lt;/span&gt;
  &lt;span class="c1"&gt;# layout 'application'&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="vi"&gt;@products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;In &lt;code&gt;app/views/products/index.html.erb&lt;/code&gt;, write this:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;turbo_frame_tag&lt;/span&gt; &lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;main_frame&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt; &lt;span class="na"&gt;do&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h4&amp;gt;&lt;/span&gt;Product List&lt;span class="nt"&gt;&amp;lt;/h4&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"card-body"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"table-responsive"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;table&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"table table-centered table-borderless table-hover nowrap"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;thead&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"table-light"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;th&amp;gt;&lt;/span&gt;Product Name&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;th&amp;gt;&lt;/span&gt;Actions&lt;span class="nt"&gt;&amp;lt;/th&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/thead&amp;gt;&lt;/span&gt;

              &lt;span class="nt"&gt;&amp;lt;tbody&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;products.each&lt;/span&gt; &lt;span class="na"&gt;do&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;product.name&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;
                      &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;button_to&lt;/span&gt; &lt;span class="na"&gt;i18n_action&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;:delete&lt;/span&gt;&lt;span class="err"&gt;),&lt;/span&gt; &lt;span class="na"&gt;product_path&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="err"&gt;),&lt;/span&gt; &lt;span class="na"&gt;method:&lt;/span&gt; &lt;span class="na"&gt;:delete&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data:&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt; &lt;span class="na"&gt;confirm:&lt;/span&gt; &lt;span class="na"&gt;i18n_action&lt;/span&gt;&lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="na"&gt;:delete_confirm&lt;/span&gt;&lt;span class="err"&gt;),&lt;/span&gt; &lt;span class="na"&gt;disable_with:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;Deleting...&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;},&lt;/span&gt; &lt;span class="na"&gt;class:&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;btn&lt;/span&gt; &lt;span class="na"&gt;btn-primary&lt;/span&gt; &lt;span class="na"&gt;btn-sm&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;
                  &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="nt"&gt;&amp;lt;/tbody&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;enable_tooltip&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="na"&gt;end&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can see when you click the &lt;code&gt;Product List&lt;/code&gt; link, only the &lt;code&gt;main_frame&lt;/code&gt; is refreshed.
And the html returned from the Server side is generated only from the code in &lt;code&gt;app/views/products/index.html.erb&lt;/code&gt;.
Code of &lt;code&gt;app/views/layouts/application.html.erb&lt;/code&gt; are not used at all.&lt;/p&gt;
&lt;h2 id="Tips"&gt;Tips&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;According to &lt;a href="https://discuss.hotwired.dev/t/destroy-record-in-turbo-frame/2731/17" rel="nofollow" target="_blank"&gt;https://discuss.hotwired.dev/t/destroy-record-in-turbo-frame/2731/17&lt;/a&gt; , you will have to use &lt;code&gt;button_to&lt;/code&gt; tag like above in the &lt;code&gt;app/views/products/index.html.erb&lt;/code&gt; to make the record deletion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Bootstrap tooltip will not be displayed because the html in &lt;code&gt;main_frame&lt;/code&gt; is generated after you click the nav link. 
So you will have to add this helper method:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;enable_tooltip&lt;/span&gt;
  &lt;span class="n"&gt;raw&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;script&amp;gt;
var tooltipTriggerList = [].slice.call(document.querySelectorAll(\'[data-bs-toggle="tooltip"]\'))
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
  return new bootstrap.Tooltip(tooltipTriggerEl)
})
&amp;lt;/script&amp;gt;'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;and call this method in &lt;code&gt;app/views/products/index.html.erb&lt;/code&gt; like the example above.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are using &lt;code&gt;Devise&lt;/code&gt;, you may find that the error message may not be displayed when typing a wrong password.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My solution is that you don't use &lt;code&gt;app/javascript/packs/frontend.js&lt;/code&gt; in the layout of sign_in page.&lt;/p&gt;

&lt;p&gt;Instead, you can write a new one like &lt;code&gt;app/javascript/packs/blank.js&lt;/code&gt;, in this &lt;code&gt;blank.js&lt;/code&gt;, don't add &lt;code&gt;import "@hotwired/turbo-rails"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And use the &lt;code&gt;blank.js&lt;/code&gt; in the new layout file &lt;code&gt;app/views/layouts/blank.html.erb&lt;/code&gt; for the Devise &lt;code&gt;sign_in&lt;/code&gt; page
, like this:&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;javascript_pack_tag&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;blank&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;stylesheet_pack_tag&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;blank&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>gazeldx</author>
      <pubDate>Thu, 11 Nov 2021 15:16:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/41872</link>
      <guid>https://ruby-china.org/topics/41872</guid>
    </item>
    <item>
      <title>[南京] 云启盛鼎诚招 Rails, JavaScript 全栈工程师 (10-25k)【已终止】</title>
      <description>&lt;h2 id="公司简介"&gt;公司简介&lt;/h2&gt;
&lt;p&gt;深圳市云启盛鼎科技有限公司南京分公司为深圳鼎信通达股份有限公司子公司。深圳鼎信通达股份有限公司成立于 2011 年，简称为鼎信通达，公司于 2016 年 12 月成功挂牌新三板，股票代码：870319。鼎信通达专注于下一代 IP 通信产品的研发、生产、销售和服务。公司现有员工 300 人，在北京、上海、杭州、武汉、成都设有分公司、子公司、研发中心。公司团队核心骨干来自于国内和国际一流通信企业，平均行业背景超过 10 年。设备及方案广泛应用于三大运营商、电力行业、金融行业、军工行业、煤矿行业、交通行业、呼叫中心及政企办公。随着业务健康发展壮大，鼎信通达计划用三年时间实现从新三板转创业版上市。               &lt;/p&gt;

&lt;p&gt;现深圳鼎信通达股份有限公司联合南京昆石网络技术有限公司、统一通信（苏州）有限公司，共同在南京设立深圳市云启盛鼎科技有限公司南京分公司，专注于开创、研发云通信平台，继续用技术创新和创新性服务为客户创造价值，以进取、创新的精神打造全球 IP 通信的领先品牌。&lt;/p&gt;
&lt;h2 id="招 Ruby, JavaScript 全栈工程师两名，初、中、高级不限"&gt;招 Ruby, JavaScript 全栈工程师两名，初、中、高级不限&lt;/h2&gt;&lt;h3 id="岗位职责"&gt;岗位职责&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;作为团队核心开发，参与核心产品对应的需求讨论、业务建模、以及技术研发和上线工作；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;修复 Bug, 优化系统，处理线上版本紧急技术问题，参与解决高并发问题；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;确保线上环境的稳定运行，保证业务的高可用性。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="后端能力"&gt;后端能力&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;计算机及相关专业，本科及以上学历。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;精通 Ruby on Rails, RSpec, simple_form, Webpacker, Sidekiq。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟悉 PostgreSQL、Redis。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;懂 Nginx, RabbitMQ, 和 Python 开发者加分。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="前端能力"&gt;前端能力&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;熟练掌握 JavaScript, CSS，Bootstrap。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟悉 ReactJS (首选）或 JQuery, Vue。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;了解 Material-UI。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="职业素养"&gt;职业素养&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;懂 Clean Code 原理，喜欢重构代码，有黑客精神。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;具备良好的产品思维，能在没有产品经理的情况下，独立设计有品味的产品。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;充满好奇心，享受 coding，学习能力强，对技术有热情，关注技术发展方向。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;具有较强的责任心，良好沟通能力和团队合作精神。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;具有良好的英语书面表达能力，过 6 级者优先。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="工作地点与时间"&gt;工作地点与时间&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;江苏省南京市秦淮区中山东路 532-2 号金蝶软件园 D 栋 205 室。不支持远程。&lt;/li&gt;
&lt;li&gt;周末双休，早 9:00 到下午 6:00。中午休息 1.5 小时，法定假日正常休息。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="薪资待遇"&gt;薪资待遇&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;10-25K 每月。&lt;/li&gt;
&lt;li&gt;五险一金。&lt;/li&gt;
&lt;li&gt;年底根据业绩情况发放奖金。&lt;/li&gt;
&lt;li&gt;双休。&lt;/li&gt;
&lt;li&gt;配备 MacBook Pro.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请有意向者发送简历邮件到 zhangjian@yunqisd.com&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Tue, 20 Jul 2021 17:32:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/41491</link>
      <guid>https://ruby-china.org/topics/41491</guid>
    </item>
    <item>
      <title>[苏州] 东湾信息招聘 Ruby 全栈程序员两名（12-20K，14 薪，双休）(已关闭)</title>
      <description>&lt;h2 id="苏州东湾信息"&gt;苏州东湾信息&lt;/h2&gt;
&lt;p&gt;我们主要服务于美国客户，目前公司团队 35 人，80% 以上为程序员。成立仅 3 年，但发展迅速。&lt;/p&gt;

&lt;p&gt;美国公司文化，双休，不加班。&lt;/p&gt;

&lt;p&gt;团队成员积极乐观，互相关心，工作氛围佳。每个月都团建。&lt;/p&gt;

&lt;p&gt;工作地址：苏州工业园区腾飞创新园 A1 塔楼 913&amp;amp;914 室&lt;/p&gt;
&lt;h2 id="职位要求"&gt;职位要求&lt;/h2&gt;&lt;h3 id="后端能力"&gt;后端能力&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;计算机相关专业，本科及以上学历。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟练掌握基本算法与数据结构。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;具有优良的编码风格和习惯。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟悉 HTTP、TCP/IP 协议，RESTful 规范。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟悉 Linux 开发环境，zsh/vim/git者优先。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;良好的 Ruby 或者 Python/PHP 语言基础及开发/重构能力。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;具有良好的英语书面表达能力，过 6 级者优先。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟练使用 Ruby On Rails 或 Flask, Django, Laravel 等主流开发框架者优先。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;了解 PostgreSQL、MySQL、Redis、Memcached 等数据库及缓存的使用和基本原理者优先。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="前端能力"&gt;前端能力&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;熟练掌握 HTML5, CSS3, JavaScript 等前端语言。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟悉 W3C 标准与 ES 规范，熟悉 Web 语义化。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟练使用至少一种 JS 框架，熟悉 ReactJS, Vue, AngularJS 中的一种。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;对代码规范有严格的要求。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="职业素养"&gt;职业素养&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;充满好奇心，享受 coding，学习能力强，对技术有热情，关注技术发展方向。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;具有较强的责任心，良好沟通能力和团队合作精神。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="薪资待遇"&gt;薪资待遇&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;每月 12-20K，14 薪（5 号发工资，试用期不打折）。&lt;/li&gt;
&lt;li&gt;五险一金。&lt;/li&gt;
&lt;li&gt;配备工作电脑（自备电脑者每月补贴 200 元）。&lt;/li&gt;
&lt;li&gt;入职即享带薪年假（5 天起）。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;请有意向者发送简历邮件到 zhangjian@easternbay.cn，来信必回 :)&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Mon, 23 Nov 2020 16:17:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/40604</link>
      <guid>https://ruby-china.org/topics/40604</guid>
    </item>
    <item>
      <title>Learn Rails 5 by Reading Source Code</title>
      <description>&lt;p&gt;Posted at: &lt;a href="https://github.com/gazeldx/Learn-Rails-by-Reading-Source-Code" rel="nofollow" target="_blank" title=""&gt;https://github.com/gazeldx/Learn-Rails-by-Reading-Source-Code&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="Learn-Rails-by-Reading-Source-Code"&gt;Learn-Rails-by-Reading-Source-Code&lt;/h2&gt;&lt;h2 id="Table of Contents"&gt;Table of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="#part-0-before-reading-rails-5-source-code" title=""&gt;Part 0: Before reading Rails 5 source code&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#what-will-you-learn-from-this-tutorial" title=""&gt;What will you learn from this tutorial?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="#part-1-your-app-an-instance-of-yourprojectapplication" title=""&gt;Part 1: Your app: an instance of YourProject::Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#part-2-config" title=""&gt;Part 2: config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="#part-3-every-request-and-response" title=""&gt;Part 3: Every request and response&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#puma" title=""&gt;Puma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#rack-apps" title=""&gt;Rack apps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#the-core-app-actiondispatchroutingrouteset-instance" title=""&gt;The core app: ActionDispatch::Routing::RouteSet instance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#render-view" title=""&gt;Render view&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#how-can-instance-variables-defined-in-controller-be-accessed-in-view-file" title=""&gt;How can instance variables defined in Controller be accessed in view file?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="#part-4-what-does--rails-server-do" title=""&gt;Part 4: What does &lt;code&gt;$ rails server&lt;/code&gt; do?&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#thor" title=""&gt;Thor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#railsserverstart" title=""&gt;Rails::Server#start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#starting-puma" title=""&gt;Starting Puma&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#conclusion" title=""&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="#exiting-puma" title=""&gt;Exiting Puma&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="#process-and-thread" title=""&gt;Process and Thread&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#send-sigterm-to-puma" title=""&gt;Send &lt;code&gt;SIGTERM&lt;/code&gt; to Puma&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="Part 0: Before reading Rails 5 source code"&gt;Part 0: Before reading Rails 5 source code&lt;/h2&gt;
&lt;p&gt;1) I suggest you learn Rack &lt;a href="http://rack.github.io/" rel="nofollow" target="_blank" title=""&gt;http://rack.github.io/&lt;/a&gt; first. &lt;/p&gt;

&lt;p&gt;In rack, an object with &lt;code&gt;call&lt;/code&gt; method is a rack app.&lt;/p&gt;

&lt;p&gt;So what is the object with &lt;code&gt;call&lt;/code&gt; method in Rails? I will answer this question in Part 1.&lt;/p&gt;

&lt;p&gt;2) You need a good IDE which can help for debugging. I use &lt;a href="https://www.jetbrains.com/" rel="nofollow" target="_blank" title=""&gt;RubyMine&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="What will you learn from this tutorial?"&gt;What will you learn from this tutorial?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How does Rails start your application?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does Rails process every request?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does Rails combine ActionController, ActionView and Routes together?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How does puma, rack, Rails work together?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What's Puma's multiple threads?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I should start with the command &lt;code&gt;$ rails server&lt;/code&gt;, but I put this to Part 4. Because it's a little bit complex.&lt;/p&gt;
&lt;h2 id="Part 1: Your app: an instance of YourProject::Application"&gt;Part 1: Your app: an instance of YourProject::Application&lt;/h2&gt;
&lt;p&gt;Assume your Rails app's class name is &lt;code&gt;YourProject::Application&lt;/code&gt; (defined in &lt;code&gt;./config/application.rb&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;First, I will give you a piece of important code.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServerCommand&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_options&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="c1"&gt;# APP_PATH is '/Users/your_name/your_project/config/application'.&lt;/span&gt;
          &lt;span class="c1"&gt;# require APP_PATH will create the 'Rails.application' object.&lt;/span&gt;
          &lt;span class="c1"&gt;# Actually, 'Rails.application' is an instance of `YourProject::Application`.&lt;/span&gt;
          &lt;span class="c1"&gt;# Rack server will start 'Rails.application'.&lt;/span&gt;
          &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt;

          &lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

          &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="c1"&gt;# 'wrapped_app' will get an well prepared app from `./config.ru` file.&lt;/span&gt;
      &lt;span class="c1"&gt;# 'wrapped_app' will return an instance of `YourProject::Application`.&lt;/span&gt;
      &lt;span class="c1"&gt;# But the instance of `YourProject::Application` returned is not created in 'wrapped_app'.&lt;/span&gt;
      &lt;span class="c1"&gt;# It has been created when `require APP_PATH` in previous code: &lt;/span&gt;
      &lt;span class="c1"&gt;# in Rails::Command::ServerCommand#perform&lt;/span&gt;
      &lt;span class="n"&gt;wrapped_app&lt;/span&gt;   

      &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Will invoke ::Rack::Server#start. &lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A rack server need to start with an &lt;code&gt;App&lt;/code&gt; object. The &lt;code&gt;App&lt;/code&gt; object should have a &lt;code&gt;call&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;config.ru&lt;/code&gt; is the conventional entry file for rack app. So let's look at it.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config.ru&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'config/environment'&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt; &lt;span class="c1"&gt;# It seems that this is the app.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let's test it by &lt;code&gt;Rails.application.respond_to?(:call)&lt;/code&gt;, it returns &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's step into &lt;code&gt;Rails.application&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="vi"&gt;@application&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@app_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

    &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:app_class&lt;/span&gt;

    &lt;span class="c1"&gt;# Oh, 'application' is a class method for module 'Rails'. It is not an object.&lt;/span&gt;
    &lt;span class="c1"&gt;# But it returns an object which is an instance of 'app_class'.&lt;/span&gt;
    &lt;span class="c1"&gt;# So it is important for us to know what class 'app_class' is.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;application&lt;/span&gt;
      &lt;span class="vi"&gt;@application&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;app_class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because &lt;code&gt;Rails.application.respond_to?(:call)&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;app_class.instance&lt;/code&gt; has a &lt;code&gt;call&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;When was &lt;code&gt;app_class&lt;/code&gt; set?&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Engine&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# This is a hooked method.&lt;/span&gt;
        &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;app_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="c1"&gt;# This line set the 'app_class'.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Rails::Application&lt;/code&gt; is inherited by &lt;code&gt;YourProject&lt;/code&gt;,&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config/application.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;YourProject&lt;/span&gt;
  &lt;span class="c1"&gt;# The hooked method `inherited` will be invoked here.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code&gt;YourProject::Application&lt;/code&gt; is the &lt;code&gt;Rails.app_class&lt;/code&gt; here.&lt;/p&gt;

&lt;p&gt;You may have a question: When does Rails execute the code in &lt;code&gt;./config/application.rb&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;To answer this question, we need to look back to &lt;code&gt;config.ru&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config.ru&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'config/environment'&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

&lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt; &lt;span class="c1"&gt;# It seems that this is the app.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config/environment.rb&lt;/span&gt;
&lt;span class="c1"&gt;# Load the Rails application.&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'application'&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

&lt;span class="c1"&gt;# Initialize the Rails application.&lt;/span&gt;
&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;initialize!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config/application.rb&lt;/span&gt;
&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'boot'&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rails/all'&lt;/span&gt;

&lt;span class="c1"&gt;# Require the gems listed in Gemfile, including any gems&lt;/span&gt;
&lt;span class="c1"&gt;# you've limited to :test, :development, or :production.&lt;/span&gt;
&lt;span class="no"&gt;Bundler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groups&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;YourProject&lt;/span&gt;
  &lt;span class="c1"&gt;# The hooked method `inherited` will be invoked here.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_defaults&lt;/span&gt; &lt;span class="mf"&gt;5.2&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:zh&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Because &lt;code&gt;YourProject::Application&lt;/code&gt; is &lt;code&gt;Rails.app_class&lt;/code&gt;, &lt;code&gt;app_class.instance&lt;/code&gt; is &lt;code&gt;YourProject::Application.instance&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But where is the &lt;code&gt;call&lt;/code&gt; method? &lt;/p&gt;

&lt;p&gt;&lt;code&gt;call&lt;/code&gt; method should be a method of &lt;code&gt;YourProject::Application.instance&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;call&lt;/code&gt; method processes every request. Here it is.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties/lib/rails/engine.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Railtie&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# This method will process every request. It is invoked by Rack. So it is very important. &lt;/span&gt;
      &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_request&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;
      &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt; &lt;span class="c1"&gt;# We will discuss the 'app' object later.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/railties/lib/rails/application.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Engine&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./config/application.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;YourProject&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ancestor's chain is &lt;code&gt;YourProject::Application &amp;lt; Rails::Application &amp;lt; Rails::Engine &amp;lt; Rails::Railtie&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So &lt;code&gt;YourProject::Application.new.respond_to?(:call)&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But what does &lt;code&gt;app_class.instance&lt;/code&gt; really do?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;instance&lt;/code&gt; is just a method name. What we really expects is something like &lt;code&gt;app_class.new&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at the definition of &lt;code&gt;instance&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties/lib/rails/application.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Engine&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;instance&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_load_hooks!&lt;/span&gt; &lt;span class="c1"&gt;# This line confused me at the beginning. &lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After a deep research, I realized that this code is equal to:&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;instance&lt;/span&gt;
  &lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Keyword 'super' means call the ancestor's same name method: 'instance'.&lt;/span&gt;
  &lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_load_hooks!&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties/lib/rails/railtie.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Railtie&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;instance&lt;/span&gt;
      &lt;span class="c1"&gt;# 'Rails::Railtie' is the top ancestor class.&lt;/span&gt;
      &lt;span class="c1"&gt;# Now 'app_class.instance' is 'YourProject::Application.new'.&lt;/span&gt;
      &lt;span class="vi"&gt;@instance&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;application&lt;/span&gt;
    &lt;span class="vi"&gt;@application&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;app_class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code&gt;YourProject::Application.new&lt;/code&gt; is &lt;code&gt;Rails.application&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rack server will start &lt;code&gt;Rails.application&lt;/code&gt; in the end.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Rails.application&lt;/code&gt; is an important object in Rails.&lt;/p&gt;

&lt;p&gt;And you'll only have one &lt;code&gt;Rails.application&lt;/code&gt; in one puma process. &lt;/p&gt;

&lt;p&gt;Multiple threads in a puma process shares the &lt;code&gt;Rails.application&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="Part 2: config"&gt;Part 2: config&lt;/h2&gt;
&lt;p&gt;The first time we see the &lt;code&gt;config&lt;/code&gt; is in &lt;code&gt;./config/application.rb&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config/application.rb&lt;/span&gt;
&lt;span class="c1"&gt;#...&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;YourProject&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Application&lt;/span&gt;
    &lt;span class="c1"&gt;# Actually, `config` is a method of `YourProject::Application`.&lt;/span&gt;
    &lt;span class="c1"&gt;# It is defined in it's grandfather's father: `Rails::Railtie`&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_defaults&lt;/span&gt; &lt;span class="mf"&gt;5.2&lt;/span&gt;  &lt;span class="c1"&gt;# Let's step into this line to see what is config.&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;i18n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default_locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:zh&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Railtie&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="c1"&gt;# Method `:config` is defined here.&lt;/span&gt;
      &lt;span class="c1"&gt;# Actually, method `:config` is delegated to another object `:instance`.&lt;/span&gt;
      &lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="ss"&gt;:config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: :instance&lt;/span&gt; 

      &lt;span class="c1"&gt;# Call `YourProject::Application.config` will actually call `YourProject::Application.instance.config`&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;instance&lt;/span&gt;
        &lt;span class="c1"&gt;# return an instance of `YourProject::Application`.&lt;/span&gt;
        &lt;span class="c1"&gt;# Call `YourProject::Application.config` will actually call `YourProject::Application.new.config`&lt;/span&gt;
        &lt;span class="vi"&gt;@instance&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; 
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Railtie&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Engine&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;instance&lt;/span&gt;
        &lt;span class="c1"&gt;# 'super' will call `:instance` method in `Railtie`, &lt;/span&gt;
        &lt;span class="c1"&gt;# which will return an instance of `YourProject::Application`.&lt;/span&gt;
        &lt;span class="n"&gt;return_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;  
        &lt;span class="n"&gt;return_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_load_hooks!&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_load_hooks!&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@ran_load_hooks&lt;/span&gt;
      &lt;span class="vi"&gt;@ran_load_hooks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt; &lt;span class="c1"&gt;# `self` is an instance of `YourProject::Application`, and `self` is `Rails.application`.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# This is the method `config`.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;
      &lt;span class="c1"&gt;# It is an instance of class `Rails::Application::Configuration`. &lt;/span&gt;
      &lt;span class="c1"&gt;# Please notice that `Rails::Application` is superclass of `YourProject::Application` (self's class).   &lt;/span&gt;
      &lt;span class="vi"&gt;@config&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_root&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;called_from&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the end, &lt;code&gt;YourProject::Application.config === Rails.application.config&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Invoke Class's &lt;code&gt;config&lt;/code&gt; method become invoke the class's instance's &lt;code&gt;config&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;configuration&lt;/span&gt;
      &lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt; 
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So &lt;code&gt;Rails.configuration === Rails.application.config&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;FYI:&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Configuration&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Engine&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Configuration&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Railtie&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;
      &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:middleware&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;
        &lt;span class="vi"&gt;@middleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Configuration&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MiddlewareStackProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Railtie&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Configuration&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Part 3: Every request and response"&gt;Part 3: Every request and response&lt;/h2&gt;
&lt;p&gt;Imagine we have this route for the home page. &lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./config/routes.rb&lt;/span&gt;
&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="s1"&gt;'home#index'&lt;/span&gt; &lt;span class="c1"&gt;# HomeController#index&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Puma"&gt;Puma&lt;/h3&gt;
&lt;p&gt;When a request is made from client, puma will process the request in &lt;code&gt;Puma::Server#process_client&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know how puma enter the method &lt;code&gt;Puma::Server#process_client&lt;/code&gt;, please read part 4 or just search 'process_client' in this document.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/puma-3.12.0/lib/puma/server.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'socket'&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="c1"&gt;# The HTTP Server itself. Serves out a single Rack app.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# This class is used by the `Puma::Single` and `Puma::Cluster` classes&lt;/span&gt;
  &lt;span class="c1"&gt;# to generate one or more `Puma::Server` instances capable of handling requests.&lt;/span&gt;
  &lt;span class="c1"&gt;# Each Puma process will contain one `Puma::Server` instacne.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# The `Puma::Server` instance pulls requests from the socket, adds them to a&lt;/span&gt;
  &lt;span class="c1"&gt;# `Puma::Reactor` where they get eventually passed to a `Puma::ThreadPool`.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# Each `Puma::Server` will have one reactor and one thread pool.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="c1"&gt;# app: #&amp;lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 &lt;/span&gt;
      &lt;span class="c1"&gt;#        @app = #&amp;lt;YourProject::Application:0x00007fcf160fb120&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;#        @config = #&amp;lt;Puma::Configuration:0x00007fcf169a6c98&amp;gt;         &lt;/span&gt;
      &lt;span class="c1"&gt;#       &amp;gt;&lt;/span&gt;
      &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Given a connection on +client+, handle the incoming requests.&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# This method support HTTP Keep-Alive so it may, depending on if the client&lt;/span&gt;
    &lt;span class="c1"&gt;# indicates that it supports keep alive, wait for another request before&lt;/span&gt;
    &lt;span class="c1"&gt;# returning.&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
          &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;handle_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Will return true in this example.&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@queue_requests&lt;/span&gt;
            &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;

            &lt;span class="no"&gt;ThreadPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clean_thread_locals&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;clean_thread_locals&lt;/span&gt;

            &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:run&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="n"&gt;close_socket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
              &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_timeout&lt;/span&gt; &lt;span class="vi"&gt;@persistent_timeout&lt;/span&gt;
              &lt;span class="vi"&gt;@reactor.add&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
              &lt;span class="k"&gt;return&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;ensure&lt;/span&gt;
        &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reset&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;close_socket&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Given the request +env+ from +client+ and a partial request body&lt;/span&gt;
    &lt;span class="c1"&gt;# in +body+, finish reading the body if there is one and invoke&lt;/span&gt;
    &lt;span class="c1"&gt;# the rack app. Then construct the response and write it back to&lt;/span&gt;
    &lt;span class="c1"&gt;# +client+&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;env&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;
      &lt;span class="c1"&gt;# ... &lt;/span&gt;
      &lt;span class="c1"&gt;# app: #&amp;lt;Puma::Configuration::ConfigMiddleware:0x00007fcf1612c338 &lt;/span&gt;
      &lt;span class="c1"&gt;#        @app = #&amp;lt;YourProject::Application:0x00007fcf160fb120&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;#        @config = #&amp;lt;Puma::Configuration:0x00007fcf169a6c98&amp;gt;         &lt;/span&gt;
      &lt;span class="c1"&gt;#       &amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@app.call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;keep_alive&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;    
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/puma-3.12.0/lib/puma/configuration.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Configuration&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ConfigMiddleware&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
        &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;Const&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PUMA_CONFIG&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@config&lt;/span&gt;
        &lt;span class="c1"&gt;# @app: #&amp;lt;YourProject::Application:0x00007fb4b1b4bcf8&amp;gt;&lt;/span&gt;
        &lt;span class="vi"&gt;@app.call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Rack apps"&gt;Rack apps&lt;/h3&gt;
&lt;p&gt;As we see when Ruby enter &lt;code&gt;Puma::Configuration::ConfigMiddleware#call&lt;/code&gt;, the &lt;code&gt;@app&lt;/code&gt; is &lt;code&gt;YourProject::Application&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;It is just the &lt;code&gt;Rails.application&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rack need a &lt;code&gt;call&lt;/code&gt; method to process request. &lt;/p&gt;

&lt;p&gt;Rails defined this &lt;code&gt;call&lt;/code&gt; method in &lt;code&gt;Rails::Engine#call&lt;/code&gt;, so that &lt;code&gt;YourProject::Application&lt;/code&gt; instance will have a &lt;code&gt;call&lt;/code&gt; method.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties/lib/rails/engine.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Engine&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Railtie&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# This method will process every request. It is invoked by Rack. &lt;/span&gt;
      &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_request&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;
      &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt; &lt;span class="c1"&gt;# The 'app' method is blow.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;
      &lt;span class="c1"&gt;# FYI,&lt;/span&gt;
      &lt;span class="c1"&gt;# caller: [&lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/application/finisher.rb:47:in `block in &amp;lt;module:Finisher&amp;gt;'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `instance_exec'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/initializable.rb:32:in `run'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/initializable.rb:63:in `block in run_initializers'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:228:in `block in tsort_each'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:350:in `block (2 levels) in each_strongly_connected_component'",&lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:431:in `each_strongly_connected_component_from'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:349:in `block in each_strongly_connected_component'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `call'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:347:in `each_strongly_connected_component'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:226:in `tsort_each'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../ruby-2.6.0/lib/ruby/2.6.0/tsort.rb:205:in `tsort_each'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/initializable.rb:61:in `run_initializers'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/application.rb:361:in `initialize!'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "/Users/lanezhang/projects/mine/free-erp/config/environment.rb:5:in `&amp;lt;top (required)&amp;gt;'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "config.ru:2:in `require_relative'", "config.ru:2:in `block in &amp;lt;main&amp;gt;'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/builder.rb:55:in `instance_eval'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/builder.rb:55:in `initialize'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "config.ru:in `new'", "config.ru:in `&amp;lt;main&amp;gt;'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/builder.rb:49:in `eval'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/builder.rb:49:in `new_from_string'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/builder.rb:40:in `parse_file'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/server.rb:320:in `build_app_and_options_from_config'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/server.rb:219:in `app'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:27:in `app'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/rack-2.0.6/lib/rack/server.rb:357:in `wrapped_app'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:92:in `log_to_stdout'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:54:in `start'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'",&lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'",&lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'",&lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'",&lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands.rb:18:in `&amp;lt;top (required)&amp;gt;'", &lt;/span&gt;
      &lt;span class="c1"&gt;# "../path/to/your_project/bin/rails:5:in `require'",&lt;/span&gt;
      &lt;span class="c1"&gt;# "../path/to/your_project/bin/rails:5:in `&amp;lt;main&amp;gt;'"&lt;/span&gt;
      &lt;span class="c1"&gt;# ]&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"caller: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;caller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

      &lt;span class="c1"&gt;# You may want to know when is the @app first time initialized.&lt;/span&gt;
      &lt;span class="c1"&gt;# It is initialized when 'config.ru' is load by rack server.&lt;/span&gt;
      &lt;span class="c1"&gt;# Please search `Rack::Server#build_app_and_options_from_config` in this document for more information.&lt;/span&gt;
      &lt;span class="c1"&gt;# When `Rails.application.initialize!` (in ./config/environment.rb) executed, @app is initialized. &lt;/span&gt;
      &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vi"&gt;@app_build_lock.synchronize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;# '@app_build_lock = Mutex.new', so multiple threads share one '@app'.&lt;/span&gt;
        &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="k"&gt;begin&lt;/span&gt;
          &lt;span class="c1"&gt;# In the end, config.middleware will be an instance of ActionDispatch::MiddlewareStack with preset instance variable @middlewares (which is an Array). &lt;/span&gt;
          &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;default_middleware_stack&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line&lt;/span&gt;
          &lt;span class="c1"&gt;# 'middleware' is a 'middleware_stack'!&lt;/span&gt;
          &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;build_middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge_into&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="c1"&gt;# FYI, this line is the last line and the result of this line is the return value for @app.&lt;/span&gt;
          &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# look at this endpoint below. We will enter method `build` later.&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#  @app: #&amp;lt;Rack::Sendfile:0x00007ff14d905f60 &lt;/span&gt;
&lt;span class="c1"&gt;#          @app=#&amp;lt;ActionDispatch::Static:0x00007ff14d906168 &lt;/span&gt;
&lt;span class="c1"&gt;#                 @app=#&amp;lt;ActionDispatch::Executor:0x00007ff14d9061b8 &lt;/span&gt;
&lt;span class="c1"&gt;#                        ...&lt;/span&gt;
&lt;span class="c1"&gt;#                           @app=#&amp;lt;Rack::ETag:0x00007fa1e540c4f8  &lt;/span&gt;
&lt;span class="c1"&gt;#                                  @app=#&amp;lt;Rack::TempfileReaper:0x00007fa1e540c520 &lt;/span&gt;
&lt;span class="c1"&gt;#                                         @app=#&amp;lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#                                 &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#                         ...    &lt;/span&gt;
&lt;span class="c1"&gt;#                        &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#                             &lt;/span&gt;
&lt;span class="c1"&gt;#                 &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#         &amp;gt;&lt;/span&gt;
      &lt;span class="vi"&gt;@app&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Defaults to an ActionDispatch::Routing::RouteSet instance.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;endpoint&lt;/span&gt;
      &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Routing&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RouteSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_with_config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties/lib/rails/application...&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Application&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Engine&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;default_middleware_stack&lt;/span&gt;
      &lt;span class="n"&gt;default_stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DefaultMiddlewareStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;default_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build_stack&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DefaultMiddlewareStack&lt;/span&gt;
      &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:paths&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:app&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
        &lt;span class="vi"&gt;@config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
        &lt;span class="vi"&gt;@paths&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_stack&lt;/span&gt;
        &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MiddlewareStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_ssl&lt;/span&gt;
            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SSL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ssl_options&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sendfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action_dispatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x_sendfile_header&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;public_file_server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enabled&lt;/span&gt;
            &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;public_file_server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Static&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;index: &lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;public_file_server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;index_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;headers: &lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;rack_cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;load_rack_cache&lt;/span&gt;
            &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"action_dispatch/http/rack_cache"&lt;/span&gt;
            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cache&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rack_cache&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allow_concurrency&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
            &lt;span class="c1"&gt;# User has explicitly opted out of concurrent request&lt;/span&gt;
            &lt;span class="c1"&gt;# handling: presumably their code is not threadsafe&lt;/span&gt;

            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Lock&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Executor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executor&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Runtime&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MethodOverride&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api_only&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RequestId&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RemoteIp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action_dispatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ip_spoofing_check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;action_dispatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trusted_proxies&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log_tags&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ShowExceptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;show_exceptions_app&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DebugExceptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;debug_exception_response_format&lt;/span&gt;

          &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cache_classes&lt;/span&gt;
            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Reloader&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reloader&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Callbacks&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Cookies&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api_only&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api_only&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_store&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_ssl&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ssl_options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:secure_cookies&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:secure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:secure&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_store&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;session_options&lt;/span&gt;
            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Flash&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api_only&lt;/span&gt;
            &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ContentSecurityPolicy&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Middleware&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Head&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ConditionalGet&lt;/span&gt;
          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ETag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"no-cache"&lt;/span&gt;

          &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TempfileReaper&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api_only&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
       &lt;span class="k"&gt;end&lt;/span&gt;
     &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/actionpack-5.2.2/lib/action_dispatch/middleware/stack.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionDispatch&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MiddlewareStack&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;build_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;Middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;    

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# See Enumerable#inject for more information.&lt;/span&gt;
      &lt;span class="n"&gt;return_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;middlewares&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="c1"&gt;# a: app, and will be changed when iterating&lt;/span&gt;
        &lt;span class="c1"&gt;# middleware: #&amp;lt;ActionDispatch::MiddlewareStack::Middleware:0x00007f8a4fada6e8&amp;gt;, 'middleware' will be switched to another instance of ActionDispatch::MiddlewareStack::Middleware when iterating&lt;/span&gt;
        &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;return_val&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;    

    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Middleware&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@klass&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;
        &lt;span class="vi"&gt;@args&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;
        &lt;span class="vi"&gt;@block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# klass is rack middleware like : Rack::TempfileReaper, Rack::ETag, Rack::ConditionalGet or Rack::Head, etc.&lt;/span&gt;
        &lt;span class="c1"&gt;# It's typical rack app to use these middlewares.&lt;/span&gt;
        &lt;span class="c1"&gt;# See https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib for more information. &lt;/span&gt;
        &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;      
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="The core app: ActionDispatch::Routing::RouteSet instance"&gt;The core app: ActionDispatch::Routing::RouteSet instance&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Paste again FYI. &lt;/span&gt;
&lt;span class="c1"&gt;#  @app: #&amp;lt;Rack::Sendfile:0x00007ff14d905f60 &lt;/span&gt;
&lt;span class="c1"&gt;#          @app=#&amp;lt;ActionDispatch::Static:0x00007ff14d906168 &lt;/span&gt;
&lt;span class="c1"&gt;#                 @app=#&amp;lt;ActionDispatch::Executor:0x00007ff14d9061b8 &lt;/span&gt;
&lt;span class="c1"&gt;#                        ...&lt;/span&gt;
&lt;span class="c1"&gt;#                           @app=#&amp;lt;Rack::ETag:0x00007fa1e540c4f8  &lt;/span&gt;
&lt;span class="c1"&gt;#                                  @app=#&amp;lt;Rack::TempfileReaper:0x00007fa1e540c520 &lt;/span&gt;
&lt;span class="c1"&gt;#                                         @app=#&amp;lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#                                 &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#                         ...    &lt;/span&gt;
&lt;span class="c1"&gt;#                        &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#                             &lt;/span&gt;
&lt;span class="c1"&gt;#                 &amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#         &amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we see in the Rack middleware stack, the last one is &lt;/p&gt;

&lt;p&gt;&lt;code&gt;@app=#&amp;lt;ActionDispatch::Routing::RouteSet:0x00007fa1e594cbe8&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionDispatch&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Routing&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RouteSet&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DEFAULT_CONFIG&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@set&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Journey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
        &lt;span class="vi"&gt;@router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Journey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@set&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;make_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# return ActionDispatch::Request.new(env)&lt;/span&gt;
        &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Journey&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Router&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@router.serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/actionpack5.2.2/lib/action_dispatch/journey/router.rb  &lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Journey&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Router&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RoutingError&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;StandardError&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:routes&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;find_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into 'find_routes'&lt;/span&gt;
          &lt;span class="n"&gt;set_params&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_parameters&lt;/span&gt;
          &lt;span class="n"&gt;path_info&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;
          &lt;span class="n"&gt;script_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;script_name&lt;/span&gt;

          &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;anchored&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;script_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;script_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;chomp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post_match&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_with?&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;parameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transform_values&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UTF_8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;

          &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_parameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set_params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;

          &lt;span class="c1"&gt;# 'route' is an instance of ActionDispatch::Journey::Route. &lt;/span&gt;
          &lt;span class="c1"&gt;# 'route.app' is an instance of ActionDispatch::Routing::RouteSet::Dispatcher.&lt;/span&gt;
          &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into method 'serve'&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;"pass"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"X-Cascade"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;script_name&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;script_name&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;       &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path_info&lt;/span&gt;
            &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_parameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;set_params&lt;/span&gt;
            &lt;span class="k"&gt;next&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"X-Cascade"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"pass"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;find_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;concat&lt;/span&gt; &lt;span class="n"&gt;custom_routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_all&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head?&lt;/span&gt;
            &lt;span class="n"&gt;match_head_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="n"&gt;match_routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_by!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:precedence&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="n"&gt;match_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;path_parameters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
          &lt;span class="n"&gt;match_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;match_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;captures&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="n"&gt;path_parameters&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_sym&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Utils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unescape_uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;match_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path_parameters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/actionpack-5.2.2/lib/action_dispatch/routing/route_set.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionDispatch&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Routing&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RouteSet&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dispatcher&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Routing&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Endpoint&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;params&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;path_parameters&lt;/span&gt; &lt;span class="c1"&gt;# params: { action: 'index', controller: 'home' }&lt;/span&gt;
          &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# controller: HomeController&lt;/span&gt;
          &lt;span class="c1"&gt;# The definition of 'make_response!' is &lt;/span&gt;
          &lt;span class="c1"&gt;# ActionDispatch::Response.create.tap { |res| res.request = request; }&lt;/span&gt;
          &lt;span class="n"&gt;res&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make_response!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
          &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:action&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
        &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RoutingError&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@raise_on_name_error&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"X-Cascade"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"pass"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]]&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="kp"&gt;private&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controller_class&lt;/span&gt;
        &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;NameError&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RoutingError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backtrace&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;    
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/actionpack-5.2.2/lib/action_controller/metal.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Metal&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;AbstractController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;
    &lt;span class="n"&gt;abstract!&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;controller_name&lt;/span&gt;
      &lt;span class="vi"&gt;@controller_name&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;demodulize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/Controller$/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;underscore&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make_response!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;ActionDispatch&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;class_attribute&lt;/span&gt; &lt;span class="ss"&gt;:middleware_stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;default: &lt;/span&gt;&lt;span class="no"&gt;ActionController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MiddlewareStack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inherited&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;middleware_stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;middleware_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Direct dispatch to the controller. Instantiates the controller, then&lt;/span&gt;
    &lt;span class="c1"&gt;# executes the action named +name+.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;middleware_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any?&lt;/span&gt;
        &lt;span class="n"&gt;middleware_stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="c1"&gt;# 'self' is HomeController, so for this line Rails will new a HomeController instance.  &lt;/span&gt;
        &lt;span class="c1"&gt;# Invoke `HomeController.ancestors`, you can find many superclasses of HomeController.&lt;/span&gt;
        &lt;span class="c1"&gt;# These are some typical superclasses of HomeController. &lt;/span&gt;
        &lt;span class="c1"&gt;# HomeController&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ApplicationController&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::Base&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActiveRecord::Railties::ControllerRuntime (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::Instrumentation (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::Rescue (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; AbstractController::Callbacks (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::ImplicitRender (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::BasicImplicitRender (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::Renderers (module included) &lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::Rendering (module included) &lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionView::Layouts (module included) &lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionView::Rendering (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionDispatch::Routing::UrlFor (module included) &lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; AbstractController::Rendering (module included)&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; ActionController::Metal&lt;/span&gt;
        &lt;span class="c1"&gt;# &amp;lt; AbstractController::Base&lt;/span&gt;
        &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;set_request!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;set_response!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit_flash&lt;/span&gt;
      &lt;span class="nb"&gt;to_a&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_a&lt;/span&gt;
      &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;AbstractController&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@_action_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;

      &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;action_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_find_action_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@_action_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;ActionNotFound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"The action '&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' could not be found for &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="vi"&gt;@_response_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

      &lt;span class="c1"&gt;# action_name: 'index'&lt;/span&gt;
      &lt;span class="n"&gt;process_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Instrumentation&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;raw_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="ss"&gt;controller: &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;action: &lt;/span&gt;&lt;span class="n"&gt;action_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;params: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filtered_parameters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;headers: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;format: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;method: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;request_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;path: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fullpath&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Notifications&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"start_processing.action_controller"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw_payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Notifications&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"process_action.action_controller"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;raw_payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;begin&lt;/span&gt;
          &lt;span class="c1"&gt;# self: #&amp;lt;HomeController:0x00007fcd3c5dfd48&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
          &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:status&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;
          &lt;span class="n"&gt;result&lt;/span&gt;
        &lt;span class="k"&gt;ensure&lt;/span&gt;
          &lt;span class="n"&gt;append_info_to_payload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/rescue.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rescue&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;
      &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"action_dispatch.show_detailed_exceptions"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;show_detailed_exceptions?&lt;/span&gt;
      &lt;span class="n"&gt;rescue_with_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;raise&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/abstract_controller/callbacks.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;AbstractController&lt;/span&gt;
  &lt;span class="c1"&gt;# = Abstract Controller Callbacks&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# Abstract Controller provides hooks during the life cycle of a controller action.&lt;/span&gt;
  &lt;span class="c1"&gt;# Callbacks allow you to trigger logic during this cycle. Available callbacks are:&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# * &amp;lt;tt&amp;gt;after_action&amp;lt;/tt&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;# * &amp;lt;tt&amp;gt;before_action&amp;lt;/tt&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;# * &amp;lt;tt&amp;gt;skip_before_action&amp;lt;/tt&amp;gt;&lt;/span&gt;
  &lt;span class="c1"&gt;# * ...&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Callbacks&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;run_callbacks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:process_action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c1"&gt;# self: #&amp;lt;HomeController:0x00007fcd3c5dfd48&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rendering&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:ref&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;compact&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/abstract_controller/base.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;AbstractController&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# self: #&amp;lt;HomeController:0x00007fcd3c5dfd48&amp;gt;, method_name: 'index'&lt;/span&gt;
      &lt;span class="c1"&gt;# In the end, method 'send_action' is method 'send' by `alias send_action send` &lt;/span&gt;
      &lt;span class="n"&gt;send_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;send_action&lt;/span&gt; &lt;span class="nb"&gt;send&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/basic_implicit_render.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;BasicImplicitRender&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# self: #&amp;lt;HomeController:0x00007fcd3c5dfd48&amp;gt;, method_name: 'index'    &lt;/span&gt;
      &lt;span class="c1"&gt;# Because 'send_action' is an alias of 'send',  &lt;/span&gt;
      &lt;span class="c1"&gt;# self.send('index', *args) will goto HomeController#index.&lt;/span&gt;
      &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;
      &lt;span class="c1"&gt;# performed?: false (for this example)&lt;/span&gt;
      &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;default_render&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;performed?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into 'default_render' later.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./your_project/app/controllers/home_controller.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeController&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="c1"&gt;# Will go back to BasicImplicitRender#send_action when method 'index' is done.&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;
    &lt;span class="c1"&gt;# Question: How does the instance variable '@users' defined in HomeController can be accessed in './app/views/home/index.html.erb' ?&lt;/span&gt;
    &lt;span class="c1"&gt;# I will answer this question later. &lt;/span&gt;
    &lt;span class="vi"&gt;@users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pluck&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;# ./app/views/home/index.html.erb
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"display-4 font-italic"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="na"&gt;t&lt;/span&gt;&lt;span class="err"&gt;('&lt;/span&gt;&lt;span class="na"&gt;home.banner_title&lt;/span&gt;&lt;span class="err"&gt;')&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;%=&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;users&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Render view"&gt;Render view&lt;/h3&gt;
&lt;p&gt;As we see in &lt;code&gt;ActionController::BasicImplicitRender::send_action&lt;/code&gt;, the last line is &lt;code&gt;default_render&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So after &lt;code&gt;HomeController#index&lt;/code&gt; is done, Ruby will execute method &lt;code&gt;default_render&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/implicit_render.rb &lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="c1"&gt;# Handles implicit rendering for a controller action that does not&lt;/span&gt;
  &lt;span class="c1"&gt;# explicitly respond with +render+, +respond_to+, +redirect+, or +head+.&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ImplicitRender&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;default_render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# Let's step into template_exists?&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;template_exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_prefixes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;variants: &lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# Rails has found the default template './app/views/home/index.html.erb', so render it.&lt;/span&gt;
        &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line later&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt; &lt;span class="s2"&gt;"No template found for &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\#&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;action_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, rendering head :no_content"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionview-5.2.2/lib/action_view/lookup_context.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LookupContext&lt;/span&gt;
    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ViewPaths&lt;/span&gt;
      &lt;span class="c1"&gt;# Rails checks whether the default template exists.&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;exists?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefixes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@view_paths.exists&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args_for_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prefixes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;partial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="ss"&gt;:template_exists?&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;exists?&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/instrumentation.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Instrumentation&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;render_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;view_runtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cleanup_view_runtime&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="no"&gt;Benchmark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ms&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;# self: #&amp;lt;HomeController:0x00007fa7e9c54278&amp;gt; &lt;/span&gt;
          &lt;span class="n"&gt;render_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into super &lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="n"&gt;render_output&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/rendering.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rendering&lt;/span&gt;
    &lt;span class="c1"&gt;# Check for double render errors and set the content_type after rendering.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;AbstractController&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;DoubleRenderError&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response_body&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into super&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/abstract_controller/rendering.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;AbstractController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rendering&lt;/span&gt;
    &lt;span class="c1"&gt;# Normalizes arguments, options and then delegates render_to_body and&lt;/span&gt;
    &lt;span class="c1"&gt;# sticks the result in &amp;lt;tt&amp;gt;self.response_body&amp;lt;/tt&amp;gt;.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_normalize_render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;rendered_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;render_to_body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:html&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;_set_html_content_type&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;_set_rendered_content_type&lt;/span&gt; &lt;span class="n"&gt;rendered_format&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;response_body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rendered_body&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Renderers&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;_render_to_body_with_renderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line and 'super' later.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# For this example, this method return nil in the end.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_render_to_body_with_renderer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# The '_renderers' is defined at line 31: `class_attribute :_renderers, default: Set.new.freeze.`&lt;/span&gt;
      &lt;span class="c1"&gt;# '_renderers' is an instance predicate method. For more information, &lt;/span&gt;
      &lt;span class="c1"&gt;# see ./gems/activesupport/lib/active_support/core_ext/class/attribute.rb  &lt;/span&gt;
      &lt;span class="n"&gt;_renderers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;_process_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;method_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Renderers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_render_with_renderer_method_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="kp"&gt;nil&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;  
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionpack-5.2.2/lib/action_controller/metal/renderers.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionController&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rendering&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;_render_in_priorities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into 'super'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/actionview-5.2.2/lib/action_view/rendering.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rendering&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_to_body&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="n"&gt;_process_options&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;_render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:variant&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;assigns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:assigns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view_context&lt;/span&gt; &lt;span class="c1"&gt;# We will step into this line later.&lt;/span&gt;

      &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt; &lt;span class="n"&gt;assigns&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;assigns&lt;/span&gt;
      &lt;span class="n"&gt;lookup_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rendered_format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:formats&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;lookup_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;variants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;variant&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;variant&lt;/span&gt;

      &lt;span class="n"&gt;view_renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionview-5.2.2/lib/action_view/renderer/renderer.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Renderer&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:partial&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;render_partial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Direct access to template rendering.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="no"&gt;TemplateRenderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@lookup_context&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionview-5.2.2/lib/action_view/renderer/template_renderer.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TemplateRenderer&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;AbstractRenderer&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@view&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
      &lt;span class="vi"&gt;@details&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract_details&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;determine_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;prepend_formats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formats&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="vi"&gt;@lookup_context.rendered_format&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;formats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:layout&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:locals&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;layout_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

      &lt;span class="n"&gt;render_with_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line&lt;/span&gt;
        &lt;span class="n"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;identifier: &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;layout: &lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;try&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:virtual_path&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="c1"&gt;# template: #&amp;lt;ActionView::Template:0x00007f822759cbc0&amp;gt;&lt;/span&gt;
          &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_layout_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render_with_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;layout&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;find_layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;formats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;layout&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@view&lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;view_flow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:layout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_layout_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionview-5.2.2/lib/action_view/template.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Template&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;instrument_render_template&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c1"&gt;# self: #&amp;lt;ActionView::Template:0x00007f89bab1efb8 &lt;/span&gt;
        &lt;span class="c1"&gt;#           @identifier="/path/to/your/project/app/views/home/index.html.erb" &lt;/span&gt;
        &lt;span class="c1"&gt;#           @source="&amp;lt;div class='container'\n ..."&lt;/span&gt;
        &lt;span class="c1"&gt;#        &amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;compile!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# method_name: "_app_views_home_index_html_erb___3699380246341444633_70336654511160" (This method is defined in 'def compile(mod)' below)&lt;/span&gt;
        &lt;span class="c1"&gt;# view: #&amp;lt;#&amp;lt;Class:0x00007ff10d6c9d18&amp;gt;:0x00007ff10ea050a8&amp;gt;, view is an instance of &amp;lt;a subclass of ActionView::Base&amp;gt; which has same instance variables defined in the instance of HomeController.&lt;/span&gt;
        &lt;span class="c1"&gt;# You will get the result html after invoking 'view.send'. &lt;/span&gt;
        &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
      &lt;span class="n"&gt;handle_render_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Compile a template. This method ensures a template is compiled&lt;/span&gt;
    &lt;span class="c1"&gt;# just once and removes the source after it is compiled.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compile!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@compiled&lt;/span&gt;

      &lt;span class="c1"&gt;# Templates can be used concurrently in threaded environments&lt;/span&gt;
      &lt;span class="c1"&gt;# so compilation and any instance variable modification must&lt;/span&gt;
      &lt;span class="c1"&gt;# be synchronized&lt;/span&gt;
      &lt;span class="vi"&gt;@compile_mutex.synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c1"&gt;# Any thread holding this lock will be compiling the template needed&lt;/span&gt;
        &lt;span class="c1"&gt;# by the threads waiting. So re-check the @compiled flag to avoid&lt;/span&gt;
        &lt;span class="c1"&gt;# re-compilation&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@compiled&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CompiledTemplates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CompiledTemplates&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_class&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;instrument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"!compile_template"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="c1"&gt;# Just discard the source if we have a virtual path. This&lt;/span&gt;
        &lt;span class="c1"&gt;# means we can get the template back.&lt;/span&gt;
        &lt;span class="vi"&gt;@source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@virtual_path&lt;/span&gt;
        &lt;span class="vi"&gt;@compiled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;encode!&lt;/span&gt;
      &lt;span class="c1"&gt;# @handler: #&amp;lt;ActionView::Template::Handlers::ERB:0x00007ff10e1be188&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@handler.call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="c1"&gt;# Make sure that the resulting String to be eval'd is in the&lt;/span&gt;
      &lt;span class="c1"&gt;# encoding of the code&lt;/span&gt;
      &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;end_src&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="sh"&gt;
        def &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;(local_assigns, output_buffer)
          _old_virtual_path, @virtual_path = @virtual_path, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="vi"&gt;@virtual_path.inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;;_old_output_buffer = @output_buffer;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;locals_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;
        ensure
          @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer
        end
&lt;/span&gt;&lt;span class="no"&gt;      end_src&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;

      &lt;span class="c1"&gt;#  source:   def _app_views_home_index_html_erb___1187260686135140546_70244801399180(local_assigns, output_buffer)&lt;/span&gt;
      &lt;span class="c1"&gt;#              _old_virtual_path, @virtual_path = @virtual_path, "home/index";_old_output_buffer = @output_buffer;;&lt;/span&gt;
      &lt;span class="c1"&gt;#              @output_buffer = output_buffer || ActionView::OutputBuffer.new;&lt;/span&gt;
      &lt;span class="c1"&gt;#              @output_buffer.safe_append='&amp;lt;div class="container"&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;#                &amp;lt;h1 class="display-4 font-italic"&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;#                  '.freeze;&lt;/span&gt;
      &lt;span class="c1"&gt;#                   @output_buffer.append=( t('home.banner_title') );&lt;/span&gt;
      &lt;span class="c1"&gt;#                   @output_buffer.append=( @users ); &lt;/span&gt;
      &lt;span class="c1"&gt;#                   @output_buffer.safe_append='&lt;/span&gt;
      &lt;span class="c1"&gt;#                &amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;#              &amp;lt;/div&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;#              '.freeze;&lt;/span&gt;
      &lt;span class="c1"&gt;#              @output_buffer.to_s&lt;/span&gt;
      &lt;span class="c1"&gt;#            ensure&lt;/span&gt;
      &lt;span class="c1"&gt;#              @virtual_path, @output_buffer = _old_virtual_path, _old_output_buffer&lt;/span&gt;
      &lt;span class="c1"&gt;#            end&lt;/span&gt;
      &lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;module_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# This line will actually define the method '_app_views_home_index_html_erb___1187260686135140546_70244801399180'&lt;/span&gt;
      &lt;span class="c1"&gt;# mod: ActionView::CompiledTemplates&lt;/span&gt;
      &lt;span class="no"&gt;ObjectSpace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_finalizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Finalizer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/actionview-5.2.2/lib/action_view/template/handler/erb.rb     &lt;/span&gt;
    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Handlers&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ERB&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;template_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;ASCII_8BIT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

          &lt;span class="n"&gt;erb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;template_source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ENCODING_TAG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;encoding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vg"&gt;$2&lt;/span&gt;

          &lt;span class="n"&gt;erb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt; &lt;span class="n"&gt;valid_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

          &lt;span class="c1"&gt;# Always make sure we return a String in the default_internal&lt;/span&gt;
          &lt;span class="n"&gt;erb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode!&lt;/span&gt;

          &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;erb_implementation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;erb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="ss"&gt;escape: &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;escape_whitelist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="ss"&gt;trim: &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;erb_trim_mode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;src&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="How can instance variables defined in Controller be accessed in view file?"&gt;How can instance variables defined in Controller be accessed in view file?&lt;/h3&gt;
&lt;p&gt;It's time to answer the question before: &lt;/p&gt;

&lt;p&gt;How can instance variables like &lt;code&gt;@users&lt;/code&gt; defined in &lt;code&gt;HomeController&lt;/code&gt; be accessed in &lt;code&gt;./app/views/home/index.html.erb&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;I will answer this question by showing the source code below.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/actionview-5.2.2/lib/action_view/rendering.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rendering&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_context&lt;/span&gt;
      &lt;span class="c1"&gt;# view_context_class is a subclass of ActionView::Base.&lt;/span&gt;
      &lt;span class="n"&gt;view_context_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line later.&lt;/span&gt;
        &lt;span class="n"&gt;view_renderer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;view_assigns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# This line will set the instance variables like '@users' in this example. Let's step into this line.  &lt;/span&gt;
        &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_assigns&lt;/span&gt;
      &lt;span class="c1"&gt;# self: #&amp;lt;HomeController:0x00007f83ecfed310&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;protected_vars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_protected_ivars&lt;/span&gt;
      &lt;span class="c1"&gt;# instance_variables is an instance method of class `Object` and it will return an array. And the array contains @users.  &lt;/span&gt;
      &lt;span class="n"&gt;variables&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;instance_variables&lt;/span&gt; 

      &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject!&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;protected_vars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_with_object&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;instance_variable_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="c1"&gt;# ret: {"marked_for_same_origin_verification"=&amp;gt;true, "users"=&amp;gt;[[1, "Lane"], [2, "John"], [4, "Frank"]]}&lt;/span&gt;
      &lt;span class="n"&gt;ret&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_context_class&lt;/span&gt;
      &lt;span class="c1"&gt;# Will return a subclass of ActionView::Base.&lt;/span&gt;
      &lt;span class="vi"&gt;@_view_context_class&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;view_context_class&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# How this ClassMethods works? Please look at ActiveSupport::Concern in ./gems/activesupport-5.2.2/lib/active_support/concern.rb&lt;/span&gt;
    &lt;span class="c1"&gt;# FYI, the method 'append_features' will be executed automatically before method 'included' executed. &lt;/span&gt;
    &lt;span class="c1"&gt;# https://apidock.com/ruby/v1_9_3_392/Module/append_features  &lt;/span&gt;
    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClassMethods&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;view_context_class&lt;/span&gt;
        &lt;span class="c1"&gt;# self: HomeController&lt;/span&gt;
        &lt;span class="vi"&gt;@view_context_class&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="k"&gt;begin&lt;/span&gt;
          &lt;span class="n"&gt;supports_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;supports_path?&lt;/span&gt;
          &lt;span class="n"&gt;routes&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:_routes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_routes&lt;/span&gt;
          &lt;span class="n"&gt;helpers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:_helpers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;_helpers&lt;/span&gt;

          &lt;span class="no"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;
              &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url_helpers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;supports_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="n"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mounted_helpers&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;helpers&lt;/span&gt;
              &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="n"&gt;helpers&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/actionview-5.2.2/lib/action_view/base.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ActionView&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;assigns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;formats&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@_config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActiveSupport&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;InheritableOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@view_renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;lookup_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;LookupContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt;
          &lt;span class="n"&gt;context&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;LookupContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;lookup_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;formats&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;formats&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;formats&lt;/span&gt;
        &lt;span class="n"&gt;lookup_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prefixes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_prefixes&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;
        &lt;span class="vi"&gt;@view_renderer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lookup_context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="vi"&gt;@cache_hit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

      &lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;assigns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="n"&gt;assign_controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;_prepare_context&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_assigns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@_assigns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
        &lt;span class="n"&gt;new_assigns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="c1"&gt;# This line will set the instance variables (like '@users') in HomeController to itself.&lt;/span&gt;
          &lt;span class="nb"&gt;instance_variable_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"@&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After all rack apps called, user will get the response.  &lt;/p&gt;
&lt;h2 id="Part 4: What does $ rails server do?"&gt;Part 4: What does &lt;code&gt;$ rails server&lt;/code&gt; do?&lt;/h2&gt;
&lt;p&gt;If you start Rails by &lt;code&gt;$ rails server&lt;/code&gt;. You may want to know what does this command do? &lt;/p&gt;

&lt;p&gt;The command &lt;code&gt;rails&lt;/code&gt; locates at &lt;code&gt;./bin/&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class="no"&gt;APP_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'../config/application'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__dir__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;require_relative&lt;/span&gt; &lt;span class="s1"&gt;'../config/boot'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rails/commands'&lt;/span&gt; &lt;span class="c1"&gt;# Let's look at this file.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./railties-5.2.2/lib/rails/commands.rb&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"rails/command"&lt;/span&gt;

&lt;span class="n"&gt;aliases&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"g"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"generate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"d"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"destroy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"c"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"console"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"s"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"server"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"db"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"dbconsole"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"r"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"runner"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"t"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"test"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt;
&lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aliases&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="c1"&gt;# command is 'server'&lt;/span&gt;

&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt; &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./railties-5.2.2/lib/rails/command.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;full_namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="c1"&gt;# command_name: 'server'  &lt;/span&gt;
        &lt;span class="c1"&gt;# After calling `find_by_namespace`, we will get this result:&lt;/span&gt;
        &lt;span class="c1"&gt;# command: Rails::Command::ServerCommand&lt;/span&gt;
        &lt;span class="n"&gt;command&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;find_by_namespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;command_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# Equals to: Rails::Command::ServerCommand.perform('server', args, config)&lt;/span&gt;
        &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt; 
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;
    &lt;span class="c1"&gt;# There is a class method 'perform' in the Base class.&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServerCommand&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Thor"&gt;Thor&lt;/h3&gt;
&lt;p&gt;Thor is a toolkit for building powerful command-line interfaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/erikhuda/thor" rel="nofollow" target="_blank" title=""&gt;https://github.com/erikhuda/thor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inheritance relationship: &lt;code&gt;Rails::Command::ServerCommand &amp;lt; Rails::Command::Base &amp;lt; Thor&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails/command/base.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Thor&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="c1"&gt;# command: 'server'&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="c1"&gt;#...&lt;/span&gt;
          &lt;span class="n"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Thor.dispatch&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/thor-0.20.3/lib/thor.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Thor&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="c1"&gt;# meth is 'server'&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;given_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;given_opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="c1"&gt;# Will new a Rails::Command::ServerCommand instance here &lt;/span&gt;
      &lt;span class="c1"&gt;# because 'self' is Rails::Command::ServerCommand.&lt;/span&gt;
      &lt;span class="n"&gt;instance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="c1"&gt;# Method 'invoke_command' is defined in Thor::Invocation. &lt;/span&gt;
      &lt;span class="c1"&gt;# command: {Thor::Command}#&amp;lt;struct Thor::Command name="server" ...&amp;gt; &lt;/span&gt;
      &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trailing&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/thor-0.20.3/lib/thor/invocation.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Thor&lt;/span&gt;
  &lt;span class="c1"&gt;# FYI, this module is included in Thor.&lt;/span&gt;
  &lt;span class="c1"&gt;# And Thor is grandfather of Rails::Command::ServerCommand&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Invocation&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;invoke_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 'invoke_command' is defined at here.&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="c1"&gt;# self: #&amp;lt;Rails::Command::ServerCommand:0x00007fdcc49791b0&amp;gt; &lt;/span&gt;
      &lt;span class="c1"&gt;# command: {Thor::Command}#&amp;lt;struct Thor::Command name="server" ...&amp;gt; &lt;/span&gt;
      &lt;span class="n"&gt;command&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/thor-0.20.3/lib/thor/command.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Thor&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:long_description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:usage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ancestor_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="c1"&gt;# instance: #&amp;lt;Rails::Command::ServerCommand:0x00007fdcc49791b0&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;# name: "server"&lt;/span&gt;
      &lt;span class="c1"&gt;# This line will invoke Rails::Command::ServerCommand#server, &lt;/span&gt;
      &lt;span class="c1"&gt;# the instance method 'server' is defined in Rails::Command::ServerCommand implicitly.&lt;/span&gt;
      &lt;span class="c1"&gt;# I will show you how the instance method 'server' is implicitly defined. &lt;/span&gt;
      &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;__send__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="k"&gt;end&lt;/span&gt;  
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/thor-0.20.3/lib/thor.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Thor&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Thor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt; &lt;span class="c1"&gt;# Will invoke hooked method 'Thor::Base.included(self)'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/thor-0.20.3/lib/thor/base.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Thor&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Base&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
      &lt;span class="c1"&gt;# 'included' is a hooked method.&lt;/span&gt;
      &lt;span class="c1"&gt;# When module 'Thor::Base' is included, method 'included' is executed. &lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;included&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
        &lt;span class="c1"&gt;# base: Thor&lt;/span&gt;
        &lt;span class="c1"&gt;# this line will define `Thor.method_added`.  &lt;/span&gt;
        &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ClassMethods&lt;/span&gt;
        &lt;span class="c1"&gt;# Module 'Invocation' is included for class 'Thor' here. &lt;/span&gt;
        &lt;span class="c1"&gt;# Because Thor is grandfather of Rails::Command::ServerCommand,&lt;/span&gt;
        &lt;span class="c1"&gt;# 'invoke_command' will be instance method of Rails::Command::ServerCommand       &lt;/span&gt;
        &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt; &lt;span class="ss"&gt;:include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Invocation&lt;/span&gt; &lt;span class="c1"&gt;# 'invoke_command' is defined in module Invocation&lt;/span&gt;
        &lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt; &lt;span class="ss"&gt;:include&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Shell&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClassMethods&lt;/span&gt;
      &lt;span class="c1"&gt;# 'method_added' is a hooked method.&lt;/span&gt;
      &lt;span class="c1"&gt;# When an instance method is created in Rails::Command::ServerCommand, &lt;/span&gt;
      &lt;span class="c1"&gt;# `method_added` will be executed.&lt;/span&gt;
      &lt;span class="c1"&gt;# So, when method `perform` is defined in Rails::Command::ServerCommand,&lt;/span&gt;
      &lt;span class="c1"&gt;# `method_added` will be executed and create_command('perform') will be invoked. &lt;/span&gt;
      &lt;span class="c1"&gt;# So in the end, method 'server' will be created by alias_method('server', 'perform').&lt;/span&gt;
      &lt;span class="c1"&gt;# And the method 'server' is for the 'server' in command `$ rails server`.&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_added&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="c1"&gt;# self: {Class} Rails::Command::ServerCommand &lt;/span&gt;
        &lt;span class="n"&gt;create_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# meth is 'perform'. Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails/command/base.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;
    &lt;span class="c1"&gt;# Rails::Command::Base is superclass of Rails::Command::ServerCommand&lt;/span&gt;
    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Base&lt;/span&gt;
      &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;create_command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;meth&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"perform"&lt;/span&gt;
            &lt;span class="c1"&gt;# Calling instance method 'server' of Rails::Command::ServerCommand &lt;/span&gt;
            &lt;span class="c1"&gt;# will be transferred to call instance method 'perform'.&lt;/span&gt;
            &lt;span class="kp"&gt;alias_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'server'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;  
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/thor-0.20.3/lib/thor/command.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Thor&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Command&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:long_description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:usage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:ancestor_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="c1"&gt;# instance: {Rails::Command::ServerCommand}#&amp;lt;Rails::Command::ServerCommand:0x00007fa5f319bf40&amp;gt;&lt;/span&gt;
      &lt;span class="c1"&gt;# name: 'server'.&lt;/span&gt;
      &lt;span class="c1"&gt;# Will actually invoke 'instance.perform(*args)'. &lt;/span&gt;
      &lt;span class="c1"&gt;# Equals to invoke Rails::Command::ServerCommand#perform(*args).&lt;/span&gt;
      &lt;span class="c1"&gt;# Let's step into  Rails::Command::ServerCommand#perform.&lt;/span&gt;
      &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;__send__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Command&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ServerCommand&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt;
      &lt;span class="c1"&gt;# This is the method will be executed when `$ rails server`.&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;server_options&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;tap&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="c1"&gt;# APP_PATH is '/Users/your_name/your_project/config/application'.&lt;/span&gt;
          &lt;span class="c1"&gt;# require APP_PATH will create the 'Rails.application' object.&lt;/span&gt;
          &lt;span class="c1"&gt;# 'Rails.application' is 'YourProject::Application.new'.&lt;/span&gt;
          &lt;span class="c1"&gt;# Rack server will start 'Rails.application'.&lt;/span&gt;
          &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt;

          &lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

          &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Rails::Server#start"&gt;Rails::Server#start&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/railties-5.2.2/lib/rails/commands/server/server_command.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rails&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
      &lt;span class="n"&gt;print_boot_information&lt;/span&gt;

      &lt;span class="nb"&gt;trap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:INT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="nb"&gt;exit&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;create_tmp_directories&lt;/span&gt;
      &lt;span class="n"&gt;setup_dev_caching&lt;/span&gt;

      &lt;span class="c1"&gt;# This line is important. Although the method name seems not.&lt;/span&gt;
      &lt;span class="n"&gt;log_to_stdout&lt;/span&gt;&lt;span class="c1"&gt;# Let step into this line.&lt;/span&gt;

      &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="c1"&gt;# Will invoke ::Rack::Server#start. I will show you later. &lt;/span&gt;
    &lt;span class="k"&gt;ensure&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Exiting"&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:daemonize&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_to_stdout&lt;/span&gt;
      &lt;span class="c1"&gt;# 'wrapped_app' will get an well prepared Rack app from './config.ru' file.&lt;/span&gt;
      &lt;span class="c1"&gt;# It's the first time invoke 'wrapped_app'.&lt;/span&gt;
      &lt;span class="c1"&gt;# The app is an instance of YourProject::Application.&lt;/span&gt;
      &lt;span class="c1"&gt;# But the app is not created in 'wrapped_app'.&lt;/span&gt;
      &lt;span class="c1"&gt;# It has been created when `require APP_PATH` in previous code,&lt;/span&gt;
      &lt;span class="c1"&gt;# just at the 'perform' method in Rails::Command::ServerCommand.   &lt;/span&gt;
      &lt;span class="n"&gt;wrapped_app&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/rack-2.0.6/lib/rack/server.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rack&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wrapped_app&lt;/span&gt;
      &lt;span class="vi"&gt;@wrapped_app&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; 
        &lt;span class="n"&gt;build_app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;
      &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;build_app_and_options_from_config&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="vi"&gt;@app&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_app_and_options_from_config&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="c1"&gt;# self.options[:config]: 'config.ru'. Let's step into this line.&lt;/span&gt;
      &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:config&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;opt_parser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="n"&gt;app&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# This method is called in Rails::Server#start&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;blk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="n"&gt;wrapped_app&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;

      &lt;span class="c1"&gt;# server: {Module} Rack::Handler::Puma&lt;/span&gt;
      &lt;span class="c1"&gt;# wrapped_app: {YourProject::Application} #&amp;lt;YourProject::Application:0x00007f7fe5523f98&amp;gt;&lt;/span&gt;
      &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wrapped_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;blk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# We will step into this line (Rack::Handler::Puma.run) later.&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# ./gems/rack/lib/rack/builder.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rack&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Builder&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# config: 'config.ru'&lt;/span&gt;
      &lt;span class="n"&gt;cfgfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_from_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfgfile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Let's guess what does 'run Rails.application' do in config.ru?&lt;/span&gt;
    &lt;span class="c1"&gt;# You may guess that: &lt;/span&gt;
    &lt;span class="c1"&gt;#   Run YourProject::Application instance.&lt;/span&gt;
    &lt;span class="c1"&gt;# But 'run' maybe not what you are thinking about.&lt;/span&gt;
    &lt;span class="c1"&gt;# Because the 'self' object in 'config.ru' is #&amp;lt;Rack::Builder:0x00007f8c861ec278 @warmup=nil, @run=nil, @map=nil, @use=[]&amp;gt;, &lt;/span&gt;
    &lt;span class="c1"&gt;# 'run' is an instance method of Rack::Builder.&lt;/span&gt;
    &lt;span class="c1"&gt;# Let's look at the definition of the 'run' method: &lt;/span&gt;
    &lt;span class="c1"&gt;# def run(app)&lt;/span&gt;
    &lt;span class="c1"&gt;#   @run = app # Just set an instance variable for Rack::Builder instance.&lt;/span&gt;
    &lt;span class="c1"&gt;# end&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_from_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder_script&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"(rackup)"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# Rack::Builder implements a small DSL to iteratively construct Rack applications.&lt;/span&gt;
      &lt;span class="nb"&gt;eval&lt;/span&gt; &lt;span class="s2"&gt;"Rack::Builder.new {&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;builder_script&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;}.to_app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="no"&gt;TOPLEVEL_BINDING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Starting Puma"&gt;Starting Puma&lt;/h3&gt;
&lt;p&gt;As we see in &lt;code&gt;Rack::Server#start&lt;/code&gt;, there is &lt;code&gt;Rack::Handler::Puma.run(wrapped_app, options, &amp;amp;blk)&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./gems/puma-3.12.0/lib/rack/handler/puma.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Rack&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Handler&lt;/span&gt;
    &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
      &lt;span class="c1"&gt;# This method is invoked in `Rack::Server#start`:&lt;/span&gt;
      &lt;span class="c1"&gt;# Rack::Handler::Puma.run(wrapped_app, options, &amp;amp;blk) &lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
        &lt;span class="n"&gt;conf&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="n"&gt;launcher&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Puma&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Launcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:events&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;begin&lt;/span&gt;
          &lt;span class="c1"&gt;# Puma will run your app (instance of YourProject::Application)&lt;/span&gt;
          &lt;span class="n"&gt;launcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
        &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Interrupt&lt;/span&gt; 
          &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"* Gracefully stopping, waiting for requests to finish"&lt;/span&gt;
          &lt;span class="n"&gt;launcher&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stop&lt;/span&gt;
          &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"* Goodbye!"&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;  
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/launcher.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="c1"&gt;# Puma::Launcher is the single entry point for starting a Puma server based on user&lt;/span&gt;
  &lt;span class="c1"&gt;# configuration. It is responsible for taking user supplied arguments and resolving them&lt;/span&gt;
  &lt;span class="c1"&gt;# with configuration in `config/puma.rb` or `config/puma/&amp;lt;env&amp;gt;.rb`.&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# It is responsible for either launching a cluster of Puma workers or a single&lt;/span&gt;
  &lt;span class="c1"&gt;# puma server.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Launcher&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;launcher_args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="vi"&gt;@runner&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;
      &lt;span class="vi"&gt;@config&lt;/span&gt;        &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;clustered?&lt;/span&gt;
        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="vi"&gt;@runner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@events&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="c1"&gt;# For this example, it is Single.new.&lt;/span&gt;
        &lt;span class="vi"&gt;@runner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Single&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@events&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;

      &lt;span class="c1"&gt;# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id` received. &lt;/span&gt;
      &lt;span class="n"&gt;setup_signals&lt;/span&gt; &lt;span class="c1"&gt;# We will discuss this line later.&lt;/span&gt;

      &lt;span class="n"&gt;set_process_title&lt;/span&gt;

      &lt;span class="vi"&gt;@runner.run&lt;/span&gt; &lt;span class="c1"&gt;# We will enter `Single.new(self, @events).run` here.&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="vi"&gt;@status&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:halt&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"* Stopping immediately!"&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:run&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:stop&lt;/span&gt;
        &lt;span class="n"&gt;graceful_stop&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:restart&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"* Restarting..."&lt;/span&gt;
        &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previous_env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@runner.before_restart&lt;/span&gt;
        &lt;span class="n"&gt;restart!&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="ss"&gt;:exit&lt;/span&gt;
        &lt;span class="c1"&gt;# nothing&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/single.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="c1"&gt;# This class is instantiated by the `Puma::Launcher` and used&lt;/span&gt;
  &lt;span class="c1"&gt;# to boot and serve a Ruby application when no puma "workers" are needed&lt;/span&gt;
  &lt;span class="c1"&gt;# i.e. only using "threaded" mode. For example `$ puma -t 1:5`&lt;/span&gt;
  &lt;span class="c1"&gt;#&lt;/span&gt;
  &lt;span class="c1"&gt;# At the core of this class is running an instance of `Puma::Server` which&lt;/span&gt;
  &lt;span class="c1"&gt;# gets created via the `start_server` method from the `Puma::Runner` class&lt;/span&gt;
  &lt;span class="c1"&gt;# that this inherits from.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Single&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Runner&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;

      &lt;span class="c1"&gt;# @server: Puma::Server.new(app, @launcher.events, @options)&lt;/span&gt;
      &lt;span class="vi"&gt;@server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start_server&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line later.&lt;/span&gt;

      &lt;span class="c1"&gt;# This line will suspend the main thread execution.&lt;/span&gt;
      &lt;span class="c1"&gt;# And the `thread`'s block (which is method `handle_servers`) will be executed.&lt;/span&gt;
      &lt;span class="c1"&gt;# See `Thread#join` for more information.&lt;/span&gt;
      &lt;span class="c1"&gt;# I will show you a simple example for using `thread.join`.&lt;/span&gt;
      &lt;span class="c1"&gt;# Please search `test_thread_join.rb` in this document.&lt;/span&gt;
      &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;

      &lt;span class="c1"&gt;# The below line will never be executed because `thread` is always running and `thread` has joined.&lt;/span&gt;
      &lt;span class="c1"&gt;# When `$ kill -s SIGTERM puma_process_id`, the below line will still not be executed&lt;/span&gt;
      &lt;span class="c1"&gt;# because the block of `Signal.trap "SIGTERM"` in `Puma::Launcher#setup_signals` will be executed.&lt;/span&gt;
      &lt;span class="c1"&gt;# If you remove the line `thread.join`, the below line will be executed, &lt;/span&gt;
      &lt;span class="c1"&gt;# but the main thread will exit after all code executed and all the threads not joined will be killed.&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"anything which will never be executed..."&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/runner.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="c1"&gt;# Generic class that is used by `Puma::Cluster` and `Puma::Single` to&lt;/span&gt;
  &lt;span class="c1"&gt;# serve requests. This class spawns a new instance of `Puma::Server` via&lt;/span&gt;
  &lt;span class="c1"&gt;# a call to `start_server`.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Runner&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;
      &lt;span class="vi"&gt;@app&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="vi"&gt;@launcher.config.app&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_server&lt;/span&gt;
      &lt;span class="n"&gt;min_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:min_threads&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;max_t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:max_threads&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

      &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Puma&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@launcher.events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min_threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min_t&lt;/span&gt;
      &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max_threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max_t&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;

      &lt;span class="n"&gt;server&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/server.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:run&lt;/span&gt;
      &lt;span class="n"&gt;queue_requests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@queue_requests&lt;/span&gt;

      &lt;span class="c1"&gt;# This part is important.&lt;/span&gt;
      &lt;span class="c1"&gt;# Remember the block of ThreadPool.new will be called when a request added to the ThreadPool instance.&lt;/span&gt;
      &lt;span class="c1"&gt;# And the block will process the request by calling method `process_client`.&lt;/span&gt;
      &lt;span class="c1"&gt;# Let's step into this line later to see how puma call the block.&lt;/span&gt;
      &lt;span class="vi"&gt;@thread_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ThreadPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@min_threads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="vi"&gt;@max_threads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="no"&gt;IOBuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

        &lt;span class="c1"&gt;# Advertise this server into the thread&lt;/span&gt;
        &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;ThreadLocalKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;

        &lt;span class="n"&gt;process_now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;queue_requests&lt;/span&gt;
          &lt;span class="n"&gt;process_now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eagerly_finish&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;  

        &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;process_now&lt;/span&gt;
          &lt;span class="c1"&gt;# Process the request. You can treat `client` as request.&lt;/span&gt;
          &lt;span class="c1"&gt;# If you want to know more about 'process_client', please read part 3 &lt;/span&gt;
          &lt;span class="c1"&gt;# or search 'process_client' in this document.  &lt;/span&gt;
          &lt;span class="n"&gt;process_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
        &lt;span class="k"&gt;else&lt;/span&gt;
          &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_timeout&lt;/span&gt; &lt;span class="vi"&gt;@first_data_timeout&lt;/span&gt;
          &lt;span class="vi"&gt;@reactor.add&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt; &lt;span class="c1"&gt;# background: true (for this example)&lt;/span&gt;
        &lt;span class="c1"&gt;# This part is important.&lt;/span&gt;
        &lt;span class="c1"&gt;# Remember puma created a thread here!&lt;/span&gt;
        &lt;span class="c1"&gt;# We will know that the newly created thread's job is waiting for requests.&lt;/span&gt;
        &lt;span class="c1"&gt;# When a request comes, the thread will transfer the request processing work to a thread in ThreadPool.&lt;/span&gt;
        &lt;span class="c1"&gt;# The method `handle_servers` in thread's block will be executed immediately &lt;/span&gt;
        &lt;span class="c1"&gt;# (executed in the newly created thread, not in the main thread).&lt;/span&gt;
        &lt;span class="vi"&gt;@thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;handle_servers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line to see what I said.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@thread&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="n"&gt;handle_servers&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_servers&lt;/span&gt;      
      &lt;span class="n"&gt;sockets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="vi"&gt;@binder.ios&lt;/span&gt;
      &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@thread_pool&lt;/span&gt;
      &lt;span class="n"&gt;queue_requests&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@queue_requests&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;

      &lt;span class="c1"&gt;# The thread is always running, because @status has been set to :run in Puma::Server#run.&lt;/span&gt;
      &lt;span class="c1"&gt;# Yes, it should always be running to transfer the incoming requests.&lt;/span&gt;
      &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:run&lt;/span&gt;
        &lt;span class="k"&gt;begin&lt;/span&gt;
          &lt;span class="c1"&gt;# This line will cause current thread waiting until a request arrives.&lt;/span&gt;
          &lt;span class="c1"&gt;# So it will be the entry of every request!&lt;/span&gt;
          &lt;span class="c1"&gt;# sockets: [#&amp;lt;IO:fd 23&amp;gt;, #&amp;lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&amp;gt;] &lt;/span&gt;
          &lt;span class="n"&gt;ios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="n"&gt;sockets&lt;/span&gt;

          &lt;span class="n"&gt;ios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;
              &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;handle_check&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept_nonblock&lt;/span&gt;
                &lt;span class="c1"&gt;# You can simply think a Puma::Client instance as a request.  &lt;/span&gt;
                &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@binder.env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                &lt;span class="c1"&gt;# ...&lt;/span&gt;

                &lt;span class="c1"&gt;# FYI, the method '&amp;lt;&amp;lt;' is redefined.&lt;/span&gt;
                &lt;span class="c1"&gt;# Add the request (client) to thread pool means &lt;/span&gt;
                &lt;span class="c1"&gt;# a thread in the pool will process this request (client).   &lt;/span&gt;
                &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

                &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait_until_not_full&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line later.&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
          &lt;span class="vi"&gt;@events.unknown_error&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Listen loop"&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;    
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/thread_pool.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadPool&lt;/span&gt;
    &lt;span class="c1"&gt;# Maintain a minimum of +min+ and maximum of +max+ threads&lt;/span&gt;
    &lt;span class="c1"&gt;# in the pool.&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="c1"&gt;# The block passed is the work that will be performed in each&lt;/span&gt;
    &lt;span class="c1"&gt;# thread.&lt;/span&gt;
    &lt;span class="c1"&gt;#&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;#..&lt;/span&gt;
      &lt;span class="vi"&gt;@mutex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Mutex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
      &lt;span class="vi"&gt;@todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# @todo is requests (in puma, they are Puma::Client instances) which need to be processed.  &lt;/span&gt;
      &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# the count of @spawned threads&lt;/span&gt;
      &lt;span class="vi"&gt;@min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# @min threads count&lt;/span&gt;
      &lt;span class="vi"&gt;@max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# @max threads count&lt;/span&gt;
      &lt;span class="vi"&gt;@block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="c1"&gt;# block will be called in method `spawn_thread` to processed a request.    &lt;/span&gt;
      &lt;span class="vi"&gt;@workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="vi"&gt;@reaper&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

      &lt;span class="vi"&gt;@mutex.synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="vi"&gt;@min.times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;spawn_thread&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Puma spawns @min count threads.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;spawn_thread&lt;/span&gt;
      &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="c1"&gt;# Create a new Thread now.&lt;/span&gt;
      &lt;span class="c1"&gt;# The block of the thread will be executed immediately and separately from the calling thread (main thread).&lt;/span&gt;
      &lt;span class="n"&gt;th&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@spawned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;spawned&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="c1"&gt;# Thread name is new in Ruby 2.3&lt;/span&gt;
        &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'puma %03i'&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;spawned&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@block&lt;/span&gt;
        &lt;span class="n"&gt;mutex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@mutex&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;

        &lt;span class="n"&gt;extra&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@extra.map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;# Pay attention to here: &lt;/span&gt;
        &lt;span class="c1"&gt;# 'while true' means this part will always be running.&lt;/span&gt;
        &lt;span class="c1"&gt;# And there will be @min count threads always running!&lt;/span&gt;
        &lt;span class="c1"&gt;# Puma uses these threads to process requests. &lt;/span&gt;
        &lt;span class="c1"&gt;# The line: 'not_empty.wait(mutex)' will make current thread waiting.  &lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
          &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

          &lt;span class="n"&gt;continue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

          &lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@trim_requested&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
                &lt;span class="vi"&gt;@trim_requested&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="n"&gt;continue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
                &lt;span class="n"&gt;not_full&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;

              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@shutdown&lt;/span&gt;
                &lt;span class="n"&gt;continue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;

              &lt;span class="vi"&gt;@waiting&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# `@waiting` is the waiting threads count.&lt;/span&gt;
              &lt;span class="n"&gt;not_full&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;signal&lt;/span&gt;

              &lt;span class="c1"&gt;# This line will cause current thread waiting&lt;/span&gt;
              &lt;span class="c1"&gt;# until `not_empty.signal` executed in some other place to wake it up .&lt;/span&gt;
              &lt;span class="c1"&gt;# Actually, `not_empty.signal` is located at `def &amp;lt;&amp;lt;(work)` in the same file.&lt;/span&gt;
              &lt;span class="c1"&gt;# You can search `def &amp;lt;&amp;lt;(work)` in this document.&lt;/span&gt;
              &lt;span class="c1"&gt;# Method `&amp;lt;&amp;lt;` is used in method `handle_servers`: `pool &amp;lt;&amp;lt; client` in Puma::Server#run.&lt;/span&gt;
              &lt;span class="c1"&gt;# `pool &amp;lt;&amp;lt; client` means add a request to the thread pool, &lt;/span&gt;
              &lt;span class="c1"&gt;# and then the waked up thread will process the request. &lt;/span&gt;
              &lt;span class="n"&gt;not_empty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt; &lt;span class="n"&gt;mutex&lt;/span&gt;

              &lt;span class="vi"&gt;@waiting&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;

            &lt;span class="c1"&gt;# `work` is the request (in puma, it's Puma::Client instance) which need to be processed.&lt;/span&gt;
            &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;continue&lt;/span&gt;  
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;continue&lt;/span&gt;

          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@clean_thread_locals&lt;/span&gt;
            &lt;span class="no"&gt;ThreadPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clean_thread_locals&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;begin&lt;/span&gt;
            &lt;span class="c1"&gt;# `block.call` will switch program to the block definition part.&lt;/span&gt;
            &lt;span class="c1"&gt;# The block definition part is in `Puma::Server#run`:&lt;/span&gt;
            &lt;span class="c1"&gt;# @thread_pool = ThreadPool.new(@min_threads,&lt;/span&gt;
            &lt;span class="c1"&gt;#                               @max_threads,&lt;/span&gt;
            &lt;span class="c1"&gt;#                               IOBuffer) do |client, buffer| #...; end&lt;/span&gt;
            &lt;span class="c1"&gt;# So please search `ThreadPool.new` in this document to look back.&lt;/span&gt;
            &lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
            &lt;span class="no"&gt;STDERR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Error reached top of thread-pool: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; (&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="vi"&gt;@workers.delete&lt;/span&gt; &lt;span class="n"&gt;th&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="c1"&gt;# end of the Thread.new.&lt;/span&gt;

      &lt;span class="vi"&gt;@workers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;th&lt;/span&gt;

      &lt;span class="n"&gt;th&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;wait_until_not_full&lt;/span&gt;
      &lt;span class="vi"&gt;@mutex.synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@shutdown&lt;/span&gt;

          &lt;span class="c1"&gt;# If we can still spin up new threads and there&lt;/span&gt;
          &lt;span class="c1"&gt;# is work queued that cannot be handled by waiting&lt;/span&gt;
          &lt;span class="c1"&gt;# threads, then accept more work until we would&lt;/span&gt;
          &lt;span class="c1"&gt;# spin up the max number of threads.&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@todo.size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@waiting&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@max&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="vi"&gt;@spawned&lt;/span&gt;

          &lt;span class="vi"&gt;@not_full.wait&lt;/span&gt; &lt;span class="vi"&gt;@mutex&lt;/span&gt; 
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Add +work+ to the todo list for a Thread to pickup and process.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@mutex.synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@shutdown&lt;/span&gt;
          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Unable to add work while shutting down"&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="c1"&gt;# work: #&amp;lt;Puma::Client:0x00007ff114ece6b0&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;# You can treat Puma::Client instance as a request.&lt;/span&gt;
        &lt;span class="vi"&gt;@todo&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;work&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@waiting&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@todo.size&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="vi"&gt;@max&lt;/span&gt;
          &lt;span class="n"&gt;spawn_thread&lt;/span&gt; &lt;span class="c1"&gt;# Create one more thread to process request. &lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="c1"&gt;# Wake up the waiting thread to process the request.&lt;/span&gt;
        &lt;span class="c1"&gt;# The waiting thread is defined in the same file: Puma::ThreadPool#spawn_thread.&lt;/span&gt;
        &lt;span class="c1"&gt;# This code is in `spawn_thread`:&lt;/span&gt;
        &lt;span class="c1"&gt;# while true &lt;/span&gt;
        &lt;span class="c1"&gt;#   # ...&lt;/span&gt;
        &lt;span class="c1"&gt;#   not_empty.wait mutex&lt;/span&gt;
        &lt;span class="c1"&gt;#   # ... &lt;/span&gt;
        &lt;span class="c1"&gt;#   block.call(work, *extra) # This line will process the request.&lt;/span&gt;
        &lt;span class="c1"&gt;# end &lt;/span&gt;
        &lt;span class="vi"&gt;@not_empty.signal&lt;/span&gt;  
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="Conclusion"&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;In conclusion, &lt;code&gt;$ rails server&lt;/code&gt; will execute &lt;code&gt;Rails::Command::ServerCommand#perform&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In &lt;code&gt;#perform&lt;/code&gt;, call &lt;code&gt;Rails::Server#start&lt;/code&gt;. Then call &lt;code&gt;Rack::Server#start&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then call &lt;code&gt;Rack::Handler::Puma.run(YourProject::Application.new)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;.run&lt;/code&gt;, Puma will new a always running Thread for &lt;code&gt;ios = IO.select(#&amp;lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&amp;gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Request is created from &lt;code&gt;ios&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;A thread in puma threadPool will process the request.&lt;/p&gt;

&lt;p&gt;The thread will invoke rack apps' &lt;code&gt;call&lt;/code&gt; to get the response for the request.&lt;/p&gt;
&lt;h3 id="Exiting Puma"&gt;Exiting Puma&lt;/h3&gt;&lt;h4 id="Process and Thread"&gt;Process and Thread&lt;/h4&gt;
&lt;p&gt;Because Puma is using multiple threads, we need to have some basic concepts about Process and Thread.&lt;/p&gt;

&lt;p&gt;This link is good for you to obtain the concepts: &lt;a href="https://stackoverflow.com/questions/4894609/will-a-cpu-process-have-at-least-one-thread" rel="nofollow" target="_blank" title=""&gt;Process and Thread&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;In the next part, you will often see &lt;code&gt;thread.join&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I will use two simple example to tell what does &lt;code&gt;thread.join&lt;/code&gt; do.&lt;/p&gt;
&lt;h5 id="Example one"&gt;Example one&lt;/h5&gt;
&lt;p&gt;Try to run &lt;code&gt;test_thread_join.rb&lt;/code&gt;. &lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./test_thread_join.rb&lt;/span&gt;
&lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"~~~~ "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# sleep 1&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"==== I am the main thread."&lt;/span&gt;

&lt;span class="c1"&gt;# thread.join # Try to uncomment these two lines to see the differences.&lt;/span&gt;
&lt;span class="c1"&gt;# puts "==== after thread.join"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You will find that if there is no &lt;code&gt;thread.join&lt;/code&gt;, you can only see &lt;code&gt;==== I am the main thread.&lt;/code&gt; in console.&lt;/p&gt;

&lt;p&gt;After you added &lt;code&gt;thread.join&lt;/code&gt;, you can see:&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="o"&gt;~~~~&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;~~~~&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;~~~~&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;in console.&lt;/p&gt;
&lt;h5 id="Example two"&gt;Example two&lt;/h5&gt;
&lt;p&gt;Try to run &lt;code&gt;test_thread_join2.rb&lt;/code&gt;. &lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ./test_thread_join2.rb&lt;/span&gt;
&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'I am arr[1]'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;# returns 4 (including the main thread)&lt;/span&gt;

&lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"~~~~~ &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;# returns 3 (because arr[0] is dead)&lt;/span&gt;

&lt;span class="c1"&gt;# arr[1].join # uncomment to see differences&lt;/span&gt;

&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"~~~~~ &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Exit main thread"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="Send SIGTERM to Puma"&gt;Send &lt;code&gt;SIGTERM&lt;/code&gt; to Puma&lt;/h4&gt;
&lt;p&gt;When you stop puma by running &lt;code&gt;$ kill -s SIGTERM puma_process_id&lt;/code&gt;, you will enter &lt;code&gt;setup_signals&lt;/code&gt; in &lt;code&gt;Puma::Launcher#run&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/launcher.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="c1"&gt;# Puma::Launcher is the single entry point for starting a Puma server based on user&lt;/span&gt;
  &lt;span class="c1"&gt;# configuration.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Launcher&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;

      &lt;span class="c1"&gt;# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. &lt;/span&gt;
      &lt;span class="n"&gt;setup_signals&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="n"&gt;set_process_title&lt;/span&gt;

      &lt;span class="vi"&gt;@runner.run&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`.&lt;/span&gt;
    &lt;span class="c1"&gt;# Signal.list #=&amp;gt; {"EXIT"=&amp;gt;0, "HUP"=&amp;gt;1, "INT"=&amp;gt;2, "QUIT"=&amp;gt;3, "ILL"=&amp;gt;4, "TRAP"=&amp;gt;5, "IOT"=&amp;gt;6, "ABRT"=&amp;gt;6, "FPE"=&amp;gt;8, "KILL"=&amp;gt;9, "BUS"=&amp;gt;7, "SEGV"=&amp;gt;11, "SYS"=&amp;gt;31, "PIPE"=&amp;gt;13, "ALRM"=&amp;gt;14, "TERM"=&amp;gt;15, "URG"=&amp;gt;23, "STOP"=&amp;gt;19, "TSTP"=&amp;gt;20, "CONT"=&amp;gt;18, "CHLD"=&amp;gt;17, "CLD"=&amp;gt;17, "TTIN"=&amp;gt;21, "TTOU"=&amp;gt;22, "IO"=&amp;gt;29, "XCPU"=&amp;gt;24, "XFSZ"=&amp;gt;25, "VTALRM"=&amp;gt;26, "PROF"=&amp;gt;27, "WINCH"=&amp;gt;28, "USR1"=&amp;gt;10, "USR2"=&amp;gt;12, "PWR"=&amp;gt;30, "POLL"=&amp;gt;29}&lt;/span&gt;
    &lt;span class="c1"&gt;# Press `Control + C` to quit means 'SIGINT'.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_signals&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="c1"&gt;# After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap "SIGTERM"`.&lt;/span&gt;
        &lt;span class="no"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trap&lt;/span&gt; &lt;span class="s2"&gt;"SIGTERM"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;graceful_stop&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;SignalException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"SIGTERM"&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"*** SIGTERM not implemented, signal based gracefully stopping unavailable!"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="no"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trap&lt;/span&gt; &lt;span class="s2"&gt;"SIGUSR2"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;restart&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"*** SIGUSR2 not implemented, signal based restart unavailable!"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="no"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trap&lt;/span&gt; &lt;span class="s2"&gt;"SIGUSR1"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="n"&gt;phased_restart&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"*** SIGUSR1 not implemented, signal based restart unavailable!"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="no"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trap&lt;/span&gt; &lt;span class="s2"&gt;"SIGINT"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Puma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jruby?&lt;/span&gt;
            &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:exit&lt;/span&gt;
            &lt;span class="n"&gt;graceful_stop&lt;/span&gt;
            &lt;span class="nb"&gt;exit&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="n"&gt;stop&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"*** SIGINT not implemented, signal based gracefully stopping unavailable!"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="no"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trap&lt;/span&gt; &lt;span class="s2"&gt;"SIGHUP"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@runner.redirected_io&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
            &lt;span class="vi"&gt;@runner.redirect_io&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="n"&gt;stop&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"*** SIGHUP not implemented, signal based logs reopening unavailable!"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;graceful_stop&lt;/span&gt;
      &lt;span class="c1"&gt;# @runner: instance of Puma::Single (for this example)&lt;/span&gt;
      &lt;span class="vi"&gt;@runner.stop_blocked&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"=== puma shutdown: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt;
      &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"- Goodbye!"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/launcher.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Single&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Runner&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;

      &lt;span class="c1"&gt;# @server: Puma::Server.new(app, @launcher.events, @options)&lt;/span&gt;
      &lt;span class="vi"&gt;@server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start_server&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;

      &lt;span class="c1"&gt;# This line will suspend the main thread execution.&lt;/span&gt;
      &lt;span class="c1"&gt;# And the `thread`'s block (which is the method `handle_servers`) will be executed.  &lt;/span&gt;
      &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stop_blocked&lt;/span&gt;
      &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"- Gracefully stopping, waiting for requests to finish"&lt;/span&gt;
      &lt;span class="vi"&gt;@control.stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@control&lt;/span&gt;
      &lt;span class="c1"&gt;# @server: instance of Puma::Server&lt;/span&gt;
      &lt;span class="vi"&gt;@server.stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/server.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Server&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;events&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="no"&gt;Events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stdio&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;
      &lt;span class="c1"&gt;# 'Puma::Util.pipe' returns `IO.pipe`.&lt;/span&gt;
      &lt;span class="vi"&gt;@check&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@notify&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Puma&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt; &lt;span class="c1"&gt;# @check, @notify is a pair.&lt;/span&gt;

      &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;stop&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="vi"&gt;@thread_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ThreadPool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@min_threads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="vi"&gt;@max_threads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                    &lt;span class="no"&gt;IOBuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;

        &lt;span class="c1"&gt;#...&lt;/span&gt;
        &lt;span class="c1"&gt;# Process the request.&lt;/span&gt;
        &lt;span class="n"&gt;process_client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
        &lt;span class="c1"&gt;#...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# 'Thread.current.object_id' returns '70144214949920', &lt;/span&gt;
      &lt;span class="c1"&gt;# which is the same as the 'Thread.current.object_id' in Puma::Server#stop.&lt;/span&gt;
      &lt;span class="c1"&gt;# Current thread is the main thread here.&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

      &lt;span class="c1"&gt;# The created @thread is the @thread in `stop` method below.&lt;/span&gt;
      &lt;span class="vi"&gt;@thread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;# FYI, this is in the puma starting process.      &lt;/span&gt;
        &lt;span class="c1"&gt;# 'Thread.current.object_id' returns '70144220123860', &lt;/span&gt;
        &lt;span class="c1"&gt;# which is the same as the 'Thread.current.object_id' in 'handle_servers' in Puma::Server#run&lt;/span&gt;
        &lt;span class="c1"&gt;# def handle_servers&lt;/span&gt;
        &lt;span class="c1"&gt;#   begin&lt;/span&gt;
        &lt;span class="c1"&gt;#     # ...&lt;/span&gt;
        &lt;span class="c1"&gt;#   ensure&lt;/span&gt;
        &lt;span class="c1"&gt;#     # FYI, the 'ensure' part is in the puma stopping process.&lt;/span&gt;
        &lt;span class="c1"&gt;#     puts "#{Thread.current.object_id}" # returns '70144220123860' too.&lt;/span&gt;
        &lt;span class="c1"&gt;#   end&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# returns '70144220123860'&lt;/span&gt;

        &lt;span class="n"&gt;handle_servers&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@thread&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="c1"&gt;# Stops the acceptor thread and then causes the worker threads to finish&lt;/span&gt;
    &lt;span class="c1"&gt;# off the request queue before finally exiting.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sync&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;# This line will set '@status = :stop',&lt;/span&gt;
      &lt;span class="c1"&gt;# and cause `ios = IO.select sockets` (in method `handle_servers`) to return result.&lt;/span&gt;
      &lt;span class="c1"&gt;# So that the code after `ios = IO.select sockets` will be executed.   &lt;/span&gt;
      &lt;span class="n"&gt;notify_safely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;STOP_COMMAND&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="c1"&gt;# 'Thread.current.object_id' returns '70144214949920', &lt;/span&gt;
      &lt;span class="c1"&gt;# which is the same as the 'Thread.current.object_id' in Puma::Server#run.&lt;/span&gt;
      &lt;span class="c1"&gt;# Current thread is exactly the main thread here.&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

      &lt;span class="c1"&gt;# The @thread is just the always running Thread created in `Puma::Server#run`.&lt;/span&gt;
      &lt;span class="c1"&gt;# Please look at method `Puma::Server#run`.&lt;/span&gt;
      &lt;span class="c1"&gt;# `@thread.join` will suspend the main thread execution.&lt;/span&gt;
      &lt;span class="c1"&gt;# And the code in @thread will continue be executed.&lt;/span&gt;
      &lt;span class="vi"&gt;@thread.join&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@thread&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;sync&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notify_safely&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="vi"&gt;@notify&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_servers&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@check&lt;/span&gt;
        &lt;span class="c1"&gt;# sockets: [#&amp;lt;IO:fd 23&amp;gt;, #&amp;lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&amp;gt;]&lt;/span&gt;
        &lt;span class="n"&gt;sockets&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;check&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="vi"&gt;@binder.ios&lt;/span&gt;
        &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@thread_pool&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:run&lt;/span&gt;
          &lt;span class="c1"&gt;# After `notify_safely(STOP_COMMAND)` in main thread, `ios = IO.select sockets` will return result.&lt;/span&gt;
          &lt;span class="c1"&gt;# FYI, `@check, @notify = IO.pipe`.&lt;/span&gt;
          &lt;span class="c1"&gt;# def notify_safely(message)&lt;/span&gt;
          &lt;span class="c1"&gt;#   @notify &amp;lt;&amp;lt; message&lt;/span&gt;
          &lt;span class="c1"&gt;# end&lt;/span&gt;
          &lt;span class="c1"&gt;# sockets: [#&amp;lt;IO:fd 23&amp;gt;, #&amp;lt;TCPServer:fd 22, AF_INET, 0.0.0.0, 3000&amp;gt;]&lt;/span&gt;
          &lt;span class="n"&gt;ios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="n"&gt;sockets&lt;/span&gt;

          &lt;span class="n"&gt;ios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt;
              &lt;span class="c1"&gt;# The @status is updated to :stop for this example in `handle_check`.&lt;/span&gt;
              &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;handle_check&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt;
              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;accept_nonblock&lt;/span&gt;
                &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@binder.env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                &lt;span class="c1"&gt;# ...&lt;/span&gt;
                &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;
                &lt;span class="n"&gt;pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait_until_not_full&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="c1"&gt;# Let's step into `graceful_shutdown`.&lt;/span&gt;
        &lt;span class="n"&gt;graceful_shutdown&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:stop&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="ss"&gt;:restart&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;ensure&lt;/span&gt;
        &lt;span class="c1"&gt;# FYI, the 'ensure' part is in the puma stopping process.&lt;/span&gt;
        &lt;span class="c1"&gt;# 'Thread.current.object_id' returns '70144220123860', &lt;/span&gt;
        &lt;span class="c1"&gt;# which is the same as the 'Thread.current.object_id' in 'Thread.new block' in Puma::Server#run&lt;/span&gt;
        &lt;span class="c1"&gt;# @thread = Thread.new do&lt;/span&gt;
        &lt;span class="c1"&gt;#   # FYI, this is in the puma starting process.&lt;/span&gt;
        &lt;span class="c1"&gt;#   puts "#{Thread.current.object_id}" # returns '70144220123860'&lt;/span&gt;
        &lt;span class="c1"&gt;#   handle_servers&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="vi"&gt;@check.close&lt;/span&gt;
        &lt;span class="vi"&gt;@notify.close&lt;/span&gt;

        &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_check&lt;/span&gt;
      &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@check.read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;STOP_COMMAND&lt;/span&gt;
        &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:stop&lt;/span&gt; &lt;span class="c1"&gt;# The @status is updated to :stop for this example. &lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;HALT_COMMAND&lt;/span&gt;
        &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:halt&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;RESTART_COMMAND&lt;/span&gt;
        &lt;span class="vi"&gt;@status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:restart&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;graceful_shutdown&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@thread_pool&lt;/span&gt;
        &lt;span class="vi"&gt;@thread_pool.shutdown&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;    
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ThreadPool&lt;/span&gt;
    &lt;span class="c1"&gt;# Tell all threads in the pool to exit and wait for them to finish.&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;shutdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@mutex.synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="vi"&gt;@shutdown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
        &lt;span class="c1"&gt;# `broadcast` will wakes up all threads waiting for this lock.&lt;/span&gt;
        &lt;span class="vi"&gt;@not_empty.broadcast&lt;/span&gt;
        &lt;span class="vi"&gt;@not_full.broadcast&lt;/span&gt;

        &lt;span class="c1"&gt;# ...&lt;/span&gt;

        &lt;span class="c1"&gt;# dup workers so that we join them all safely&lt;/span&gt;
        &lt;span class="c1"&gt;# @workers is an array.   &lt;/span&gt;
        &lt;span class="c1"&gt;# @workers.dup will not create new thread.&lt;/span&gt;
        &lt;span class="c1"&gt;# @workers is an instance variable and will be changed when shutdown (by `@workers.delete th`). &lt;/span&gt;
        &lt;span class="c1"&gt;# So ues @workers.dup here.&lt;/span&gt;
        &lt;span class="vi"&gt;@workers.dup&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Wait for threads to finish without force shutdown.&lt;/span&gt;
      &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="vi"&gt;@workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="c1"&gt;#..&lt;/span&gt;
      &lt;span class="vi"&gt;@mutex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Mutex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
      &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# The count of @spawned threads.&lt;/span&gt;
      &lt;span class="vi"&gt;@todo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="c1"&gt;# @todo is requests (in puma, it's Puma::Client instance) which need to be processed.  &lt;/span&gt;
      &lt;span class="vi"&gt;@min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# @min threads count&lt;/span&gt;
      &lt;span class="vi"&gt;@block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="c1"&gt;# block will be called in method `spawn_thread` to process a request.    &lt;/span&gt;
      &lt;span class="vi"&gt;@workers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

      &lt;span class="vi"&gt;@mutex.synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="vi"&gt;@min.times&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;spawn_thread&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;# Puma spawns @min count threads.&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;spawn_thread&lt;/span&gt;
      &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

      &lt;span class="c1"&gt;# Run a new Thread now.&lt;/span&gt;
      &lt;span class="c1"&gt;# The block of the thread will be executed separately from the calling thread. &lt;/span&gt;
      &lt;span class="n"&gt;th&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@spawned&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;spawned&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@block&lt;/span&gt;
        &lt;span class="n"&gt;mutex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@mutex&lt;/span&gt;
        &lt;span class="c1"&gt;#...&lt;/span&gt;

        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
          &lt;span class="n"&gt;work&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;

          &lt;span class="n"&gt;continue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;

          &lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt;
              &lt;span class="c1"&gt;# ...&lt;/span&gt;

              &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@shutdown&lt;/span&gt;
                &lt;span class="n"&gt;continue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;
              &lt;span class="k"&gt;end&lt;/span&gt;

              &lt;span class="c1"&gt;# ...&lt;/span&gt;
              &lt;span class="c1"&gt;# After `@not_empty.broadcast` is executed in '#shutdown', `not_empty` is waked up.&lt;/span&gt;
              &lt;span class="c1"&gt;# Ruby will continue to execute the next line here.&lt;/span&gt;
              &lt;span class="n"&gt;not_empty&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&lt;/span&gt; &lt;span class="n"&gt;mutex&lt;/span&gt;

              &lt;span class="vi"&gt;@waiting&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="k"&gt;end&lt;/span&gt;

            &lt;span class="c1"&gt;# ...&lt;/span&gt;
          &lt;span class="k"&gt;end&lt;/span&gt;

          &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;continue&lt;/span&gt;

          &lt;span class="c1"&gt;# ...&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;

        &lt;span class="n"&gt;mutex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;synchronize&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="vi"&gt;@spawned&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
          &lt;span class="vi"&gt;@workers.delete&lt;/span&gt; &lt;span class="n"&gt;th&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt; &lt;span class="c1"&gt;# end of the Thread.new.&lt;/span&gt;

      &lt;span class="vi"&gt;@workers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;th&lt;/span&gt;

      &lt;span class="n"&gt;th&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So all the threads in the ThreadPool joined and finished.&lt;/p&gt;

&lt;p&gt;Let's inspect the caller in block of &lt;code&gt;Signal.trap "SIGTERM"&lt;/code&gt; below.&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .gems/puma-3.12.0/lib/puma/launcher.rb&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Puma&lt;/span&gt;
  &lt;span class="c1"&gt;# Puma::Launcher is the single entry point for starting a Puma server based on user&lt;/span&gt;
  &lt;span class="c1"&gt;# configuration.&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Launcher&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;
      &lt;span class="c1"&gt;#...&lt;/span&gt;

      &lt;span class="c1"&gt;# Set the behaviors for signals like `$ kill -s SIGTERM puma_process_id`. &lt;/span&gt;
      &lt;span class="n"&gt;setup_signals&lt;/span&gt; &lt;span class="c1"&gt;# Let's step into this line.&lt;/span&gt;

      &lt;span class="n"&gt;set_process_title&lt;/span&gt;

      &lt;span class="c1"&gt;# Process.pid: 42264 &lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process.pid: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

      &lt;span class="vi"&gt;@runner.run&lt;/span&gt;

      &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;setup_signals&lt;/span&gt;
      &lt;span class="c1"&gt;# ...&lt;/span&gt;
      &lt;span class="k"&gt;begin&lt;/span&gt;
        &lt;span class="c1"&gt;# After running `$ kill -s SIGTERM puma_process_id`, Ruby will execute the block of `Signal.trap "SIGTERM"`.&lt;/span&gt;
        &lt;span class="no"&gt;Signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trap&lt;/span&gt; &lt;span class="s2"&gt;"SIGTERM"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
          &lt;span class="c1"&gt;# I inspect `caller` to see the caller stack.&lt;/span&gt;
          &lt;span class="c1"&gt;# caller: [&lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/puma-3.12.0/lib/puma/single.rb:118:in `join'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/puma-3.12.0/lib/puma/single.rb:118:in `run'",&lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/puma-3.12.0/lib/puma/launcher.rb:186:in `run'",&lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/puma-3.12.0/lib/rack/handler/puma.rb:70:in `run'",&lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/rack-2.0.6/lib/rack/server.rb:298:in `start'",&lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:149:in `block in perform'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `tap'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:144:in `perform'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/thor-0.20.3/lib/thor/command.rb:27:in `run'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/thor-0.20.3/lib/thor/invocation.rb:126:in `invoke_command'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/thor-0.20.3/lib/thor.rb:391:in `dispatch'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/command/base.rb:65:in `perform'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/command.rb:46:in `invoke'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../gems/railties-5.2.2/lib/rails/commands.rb:18:in `&amp;lt;top (required)&amp;gt;'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../path/to/your_project/bin/rails:5:in `require'", &lt;/span&gt;
          &lt;span class="c1"&gt;#   "../path/to/your_project/bin/rails:5:in `&amp;lt;main&amp;gt;'"&lt;/span&gt;
          &lt;span class="c1"&gt;# ]&lt;/span&gt;
          &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"caller: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;caller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inspect&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

          &lt;span class="c1"&gt;# Process.pid: 42264 which is the same as the `Process.pid` in the Puma::Launcher#run.&lt;/span&gt;
          &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Process.pid: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

          &lt;span class="n"&gt;graceful_stop&lt;/span&gt;

          &lt;span class="c1"&gt;# This SignalException is not rescued in the caller stack.&lt;/span&gt;
          &lt;span class="c1"&gt;# So in the the caller stack, Ruby will goto the `ensure` part in&lt;/span&gt;
          &lt;span class="c1"&gt;# "../gems/railties-5.2.2/lib/rails/commands/server/server_command.rb:55:in `start'".&lt;/span&gt;
          &lt;span class="c1"&gt;# So the last code executed is `puts "Exiting" unless @options &amp;amp;&amp;amp; options[:daemonize]`&lt;/span&gt;
          &lt;span class="c1"&gt;# when running `$ kill -s SIGTERM puma_process_id`.&lt;/span&gt;
          &lt;span class="c1"&gt;# You can search `puts "Exiting"` in this document to see it.&lt;/span&gt;
          &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="no"&gt;SignalException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"SIGTERM"&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
      &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="no"&gt;Exception&lt;/span&gt;
        &lt;span class="c1"&gt;# This `rescue` is only for `Signal.trap "SIGTERM"`, not for `raise SignalException, "SIGTERM"`.&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="s2"&gt;"*** SIGTERM not implemented, signal based gracefully stopping unavailable!"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Welcome to point out the mistakes in this article :)&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Tue, 05 Mar 2019 15:08:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/38195</link>
      <guid>https://ruby-china.org/topics/38195</guid>
    </item>
    <item>
      <title>只收邮费转 4 本 Ruby 经典书 (己结帖)</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/e1ac92ba-ca01-4606-b77f-1b3661d5d8c3.jpeg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2018/841c322a-77ed-4851-a223-aec39dfda3f3.jpeg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2018/8a950433-1ba1-49cc-ba4d-a860f8c498d2.jpeg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2018/b75250af-1996-48b1-953a-f9b58225de73.jpeg!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;邮费 12 元。请加我微信，当你把邮费转我后，就在本帖下留言结帖。&lt;/p&gt;

&lt;p&gt;谢谢。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Sun, 21 Oct 2018 09:04:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/37657</link>
      <guid>https://ruby-china.org/topics/37657</guid>
    </item>
    <item>
      <title>用源 gems.ruby-china.org 报错，之后用 ruby.taobao.org 替代后好了，请管理员关注下</title>
      <description>&lt;p&gt;报错如下：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;actionview &lt;span class="nt"&gt;-v&lt;/span&gt; 4.1.7
Fetching: actionview-4.1.7.gem &lt;span class="o"&gt;(&lt;/span&gt; 10%&lt;span class="o"&gt;)&lt;/span&gt;
ERROR:  While executing gem ... &lt;span class="o"&gt;(&lt;/span&gt;Gem::RemoteFetcher::FetchError&lt;span class="o"&gt;)&lt;/span&gt;
    too many connection resets &lt;span class="o"&gt;(&lt;/span&gt;https://gems-ruby-china.b0.upaiyun.com/gems/actionview-4.1.7.gem&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>gazeldx</author>
      <pubDate>Tue, 03 May 2016 13:56:11 +0800</pubDate>
      <link>https://ruby-china.org/topics/29902</link>
      <guid>https://ruby-china.org/topics/29902</guid>
    </item>
    <item>
      <title>是时候搞点新玩意了——用 react-native 开发跨平台 APP</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/facebook/react-native" rel="nofollow" target="_blank"&gt;https://github.com/facebook/react-native&lt;/a&gt;
从去年发布，短短 1 年出头，github 关注度已经到 30665。&lt;/p&gt;

&lt;p&gt;中文社区 &lt;a href="http://reactnative.cn/" rel="nofollow" target="_blank"&gt;http://reactnative.cn/&lt;/a&gt; 也搞得很活跃。&lt;/p&gt;

&lt;p&gt;从我自己的使用看，两年前曾经尝试用 Ruby Motion 搞 APP 开发，1 天时间没把 helloWorld 搞出来。
1 个月前用 react-native 搞 APP 开发，1 天时间把 helloWorld 搞出来了，之间也遇到一些问题，都被自己解决了，见： &lt;a href="http://gazeldx.github.io/react-native/2016/03/19/React-native/" rel="nofollow" target="_blank"&gt;http://gazeldx.github.io/react-native/2016/03/19/React-native/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;搞了这么多年 Web 了，是时候搞点新玩意了。&lt;/p&gt;

&lt;p&gt;本来想研究深入点，把自己的 APP 上线后，开源让大家围观的。
不过由于近期本人重回股市，业余时间重点切换了，只能以此文引诱下大家了。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Mon, 18 Apr 2016 13:55:15 +0800</pubDate>
      <link>https://ruby-china.org/topics/29759</link>
      <guid>https://ruby-china.org/topics/29759</guid>
    </item>
    <item>
      <title>我的 Sinatra 实践</title>
      <description>&lt;p&gt;一直以来，我都在社区积极地实践 Sinatra。这次正好在我发起的“公益读书”活动项目中完整的实践了一次。以前自己的 Sinatra 项目好多都是&lt;a href="http://www.sinatrarb.com/intro.html#Sinatra::Base%20-%20Middleware,%20Libraries,%20and%20Modular%20Apps" rel="nofollow" target="_blank" title=""&gt;Classic style&lt;/a&gt;，这一次用&lt;a href="http://www.sinatrarb.com/intro.html#Serving%20a%20Modular%20Application" rel="nofollow" target="_blank" title=""&gt;Modular Application&lt;/a&gt;，并且目录结构和 Rails 的目录结构也很像。&lt;/p&gt;

&lt;p&gt;Sinatra 做项目的特别之处在于，您的代码都是您可以掌控的，不会像 Rails 那样一下子引入那么多的 gem，而且好多并不是您需要的。因此用 Sinatra 对您的 DIY 能力是种考验。&lt;/p&gt;
&lt;h2 id="美德公益读书活动"&gt;美德公益读书活动&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://meidebook.com/about" rel="nofollow" target="_blank" title=""&gt;公益读书活动详情&lt;/a&gt;
&lt;a href="https://github.com/gazeldx/meidebook" rel="nofollow" target="_blank" title=""&gt;源代码在 https://github.com/gazeldx/meidebook&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="功能展示"&gt;功能展示&lt;/h2&gt;
&lt;p&gt;包含“注册、登录、搜索图书、查看图书信息、评论图书、发表读书心得、上传图片、验证码等”功能。&lt;/p&gt;

&lt;p&gt;请访问&lt;a href="http://meidebook.com" rel="nofollow" target="_blank" title=""&gt;美德公益图书 - 首页&lt;/a&gt;体验相关功能（更侧重手机访问体验）。&lt;/p&gt;
&lt;h2 id="安装本项目"&gt;安装本项目&lt;/h2&gt;
&lt;p&gt;采用&lt;a href="www.sinatrarb.com" title=""&gt;Sinatra&lt;/a&gt;架构搭建本项目，数据库操作用&lt;a href="http://sequel.jeremyevans.net/" rel="nofollow" target="_blank" title=""&gt;Sequel&lt;/a&gt;，数据库用&lt;a href="http://sqlite.com/" rel="nofollow" target="_blank" title=""&gt;SQLite&lt;/a&gt;，界面用&lt;a href="http://weui.github.io/weui/" rel="nofollow" target="_blank" title=""&gt;WeUI&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id="安装Ruby"&gt;安装 Ruby&lt;/h2&gt;&lt;h3 id="安装rbenv"&gt;安装&lt;a href="https://github.com/rbenv/rbenv" rel="nofollow" target="_blank" title=""&gt;rbenv&lt;/a&gt;
&lt;/h3&gt;
&lt;p&gt;相比 RVM，我更喜欢 rbenv。RVM 中我想要的功能，rbenv 都有。用了 rbenv，你会发现一些 RVM 的不便之处。&lt;/p&gt;
&lt;h3 id="安装rbenv-gemset"&gt;安装&lt;a href="https://github.com/jf/rbenv-gemset" rel="nofollow" target="_blank" title=""&gt;rbenv-gemset&lt;/a&gt;
&lt;/h3&gt;&lt;h2 id="安装其它软件"&gt;安装其它软件&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.imagemagick.org/" rel="nofollow" target="_blank" title=""&gt;ImageMagick&lt;/a&gt; 用于图片处理。&lt;/p&gt;
&lt;h2 id="安装本程序"&gt;安装本程序&lt;/h2&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git clone git@github.com:gazeldx/meidebook.git
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /path/to/meidebook
&lt;span class="nv"&gt;$ &lt;/span&gt;gem &lt;span class="nb"&gt;install &lt;/span&gt;bundler
&lt;span class="nv"&gt;$ &lt;/span&gt;bundle &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;sequel &lt;span class="nt"&gt;-m&lt;/span&gt; db/migrations sqlite://db/book_development.db &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="c"&gt;# 创建数据库&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;puma &lt;span class="c"&gt;# 启动项目，这时可以访问 http://localhost:9292/ 了&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="代码说明"&gt;代码说明&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/gazeldx/meidebook/blob/master/config.ru" rel="nofollow" target="_blank" title=""&gt;./config.ru&lt;/a&gt;是第一个被加载的文件，&lt;a href="https://github.com/gazeldx/meidebook/blob/master/controllers/application_controller.rb" rel="nofollow" target="_blank" title=""&gt;./controllers/application_controller.rb&lt;/a&gt;是一个很重要的文件。&lt;/p&gt;
&lt;h2 id="安装Nginx并运行程序在80端口"&gt;安装 Nginx 并运行程序在 80 端口&lt;/h2&gt;
&lt;p&gt;详见&lt;a href="https://github.com/gazeldx/meidebook/blob/master/deploy/README.md" rel="nofollow" target="_blank" title=""&gt;./deploy/README.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;其它使用帮助见&lt;a href="https://github.com/gazeldx/meidebook/wiki" rel="nofollow" target="_blank" title=""&gt;Wiki&lt;/a&gt;&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Sun, 24 Jan 2016 14:35:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/28836</link>
      <guid>https://ruby-china.org/topics/28836</guid>
    </item>
    <item>
      <title>公益读书</title>
      <description>&lt;p&gt;  你一定读过对自己帮助很大的书，而且相信这些书&lt;strong&gt;对别人也会有莫大的帮助&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;  为什么不把这些好书送给别人呢？&lt;/p&gt;

&lt;p&gt;  为了让正能量得以不断传承，我们希望&lt;strong&gt;受赠者在一个月内读完，并把书传递给下个读者&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/0158f6115ef5c7d30b10f0f16cbfa420.jpg" title="" alt=""&gt;
为让传书游戏更有趣，捐书人写下互动文字&lt;/p&gt;
&lt;h3 id="捐书人游戏玩法"&gt;捐书人游戏玩法&lt;/h3&gt;
&lt;p&gt;  （一）我们建议捐书人&lt;strong&gt;只捐自己最爱的书&lt;/strong&gt;。那些在自己书柜里剩下的、占地方、以后又不会看的书，不建议您用这样的方式捐（如果要捐，你可以不写引导扩散的话，这样就只会影响到一个读者）。因为读者在看您捐的书时，是要花宝贵的时间的。要给就给读者大餐，看完后大呼过瘾。我想这时，您也会感到由衷的开心，特别是这些书被广泛扩散时。表面上，你损失了一本心爱的好书。实际上，你可以再买一本，损失不过十几块钱。而回报，捐过就知道。&lt;/p&gt;

&lt;p&gt;  （二）我们建议捐书人在书的第一页空白处写上活动简介（如上图）。&lt;/p&gt;

&lt;p&gt;  之后写上自己的昵称、联系方式、日期和口讯（写在一行），并在本行之后划上一行行横线，在每一行开头写上读者 1、读者 2、读者 N，为以后的读者互动提供引导。&lt;/p&gt;

&lt;p&gt;  （三）捐书人可以为本书取一个编号，这样，在美德公益图书网站（筹建中）&lt;a href="http://meidebook.com" rel="nofollow" target="_blank"&gt;http://meidebook.com&lt;/a&gt; 上，可以根据此编号查询到该书的当前状态（因为热心的读者会把扉页拍成照片上传）。每一本捐出的图书都对应了一个唯一的 URL，如：上图所示，捐书人设定的图书编号是“loveme1982”，对应的 URL 就是 &lt;a href="http://meidebook.com/loveme1982" rel="nofollow" target="_blank"&gt;http://meidebook.com/loveme1982&lt;/a&gt; ，捐书人和读者可以在此 URL 中聊天，因为 loveme1982 是由捐书人设定的，这保证了进入该 URL 的人都是拿到了本书的读者。&lt;/p&gt;

&lt;p&gt;  在该页面，会关联该捐书人捐过的所有图书。自然，这个页面就成了捐书人的好书推荐。更多好书就这样被读者发现。&lt;/p&gt;
&lt;h3 id="读者游戏玩法"&gt;读者游戏玩法&lt;/h3&gt;
&lt;p&gt;  （一）我们建议读者在一个月内读完本书，并把书传递给下一位读者。在传递时，请把游戏玩法和下一位读者简单说明一下。读者如果不愿意读完，可以立刻把书传出去。这样做的目的是加速图书的流传，让正能量传播地快些。&lt;/p&gt;

&lt;p&gt;  （二）&lt;strong&gt;读者可以无条件的中止传递，自行处置手中的图书&lt;/strong&gt;。因为我们希望&lt;strong&gt;最好的书得到最好的流传&lt;/strong&gt;。为防止“劣币驱逐良币”现象发生，我们加入了本条规则。我们对书顺利传递充满信心，对终结传递倒是有些担心。因为想终结一本书的理由很多，如书中讲述的道理不科学，内容不够正能量等。但大多数人都会想：“可能别人认为这本书好呢？如果我终结了这本书，我内心会不安。”请不要感到不安，无条件、无理由的终结一本书，是“美德公益图书”的游戏规则，我们非常鼓励这种行为。因为你对这本书的终结，为更高质量的图书的广泛流传留出了空间。&lt;/p&gt;
&lt;h3 id="运营建议"&gt;运营建议&lt;/h3&gt;
&lt;p&gt;  如果你有兴趣开发运营类似的网站，我就更开心了。我祝福你能运营得比“美德公益图书”影响力更大（当我把这个想法告诉我的同事们的时候，就有个同事因为某些游戏规则和我的想法不一致，要自己造平台了）。&lt;/p&gt;

&lt;p&gt;  我建议您在运营时注意下图书的质量，好书让这个世界更美好，劣质的书相反。&lt;/p&gt;

&lt;p&gt;  其实每个捐书者在捐书时，都是一个崭新的开始。如果捐书有任何想法，完全可以制定自己的游戏玩法，不受“美德公益图书”的玩法限制。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Sat, 26 Dec 2015 23:02:58 +0800</pubDate>
      <link>https://ruby-china.org/topics/28534</link>
      <guid>https://ruby-china.org/topics/28534</guid>
    </item>
    <item>
      <title>一个 String 类型处理不当导致的性能问题，在导出 CSV 文件等�场景不注意就会中招</title>
      <description>&lt;p&gt;一种的生成 csv 文件的做法：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="vi"&gt;@customers.each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="o"&gt;.......&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种做法存在性能问题，特别是 customers 达到 1 万条以上，并且每一行内容比较长的时候。
原因是 csv 这个字符串变量太大了（达到 1M），再往 csv 的末尾追加内容会比较吃力，这种情况，生成 csv 最终结果要 1 分钟。&lt;/p&gt;

&lt;p&gt;解决的办法：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="vi"&gt;@customers.each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;csv&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="o"&gt;.......&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;csv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;csv 从字符串变成了 Array, 避免了超大 String 的可能。和上述同样场景下，生成 csv 最终结果只要 5 秒。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Wed, 16 Dec 2015 10:07:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/28402</link>
      <guid>https://ruby-china.org/topics/28402</guid>
    </item>
    <item>
      <title>请管理员解释下：为什么我提交的开源项目在 Sites 里面始终不能显示？</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/gazeldx/ruby-db-admin" rel="nofollow" target="_blank"&gt;https://github.com/gazeldx/ruby-db-admin&lt;/a&gt; 这是本人开发的基于 Ruby 的数据库管理系统。
我曾经再次提交到 &lt;a href="https://ruby-china.org/sites" rel="nofollow" target="_blank"&gt;https://ruby-china.org/sites&lt;/a&gt; ，当时是成功了，可过一阵子再去看，就消失了。
请问管理员这是什么原因？上 Sites 有什么要求吗？&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Sun, 15 Nov 2015 13:11:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/28064</link>
      <guid>https://ruby-china.org/topics/28064</guid>
    </item>
    <item>
      <title>建议 Ruby-China 把 “求职” 全部替换为 “找工作”</title>
      <description>&lt;p&gt;“求职”，一下子让人找工作的人感觉自己在求职位。
其实只是找工作，谁也不求谁啊。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Tue, 29 Sep 2015 13:42:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/27515</link>
      <guid>https://ruby-china.org/topics/27515</guid>
    </item>
    <item>
      <title>[北京] 诚觅 Ruby App 服务端工程师一名 20K</title>
      <description>&lt;h4 id="团队风格"&gt;团队风格&lt;/h4&gt;
&lt;p&gt;一、小而美
目前研发团队规模已经扩大到 9 人，苏州 6 人，北京 3 人。
APP 团队已经在北京初步搭建（尚缺一个 Rubyist——你），苏州研发团队专注于通讯 SaaS 平台服务提供，北京团队专注于移动互联产品。
二、目前团队基本上是无人管理的状态，自发做事，自我管理。
三、领导处于经常被员工顶撞的状态。&lt;/p&gt;
&lt;h2 id="工作要求"&gt;工作要求&lt;/h2&gt;&lt;h3 id="工作职责"&gt;工作职责&lt;/h3&gt;
&lt;p&gt;1、为 APP（安卓和 iOS）提供 API 数据支持
2、服务端设计与开发&lt;/p&gt;
&lt;h3 id="个性方面"&gt;个性方面&lt;/h3&gt;
&lt;p&gt;1、有担当
2、学习能力佳，英文佳
3、性格开朗，乐于分享
4、对代码有洁癖者佳（有过度洁癖者请谨慎）&lt;/p&gt;
&lt;h3 id="技术栈"&gt;技术栈&lt;/h3&gt;
&lt;p&gt;1、Ruby 基础扎实
2、熟悉 Rails, Grape, Sinatra 等架构
3、做过 Node.js
4、Linux, 关系型和非关系型数据库，Redis, Git 等
5、有 APP API 开发经验者优&lt;/p&gt;
&lt;h2 id="福利待遇"&gt;福利待遇&lt;/h2&gt;
&lt;p&gt;1、基本月工资 20K 左右，视能力而定
2、股份期权激励
3、工作日 9 点 -18 点，中午休息一个小时，双休，不加班
4、五险一金&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Sat, 12 Sep 2015 15:48:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/27298</link>
      <guid>https://ruby-china.org/topics/27298</guid>
    </item>
    <item>
      <title>[苏州] 诚招 Ruby &amp; Rails, JavaScript 全栈工程师</title>
      <description>&lt;h2 id="对您的期待"&gt;对您的期待&lt;/h2&gt;
&lt;p&gt;我们期待您是这样的一个伙伴：
1 对计算机技术孜孜追求，甚至有些代码洁癖。
2 不畏惧挑战，勇于担当。
3 学习能力佳，英文佳（必须）。
4 性格开朗，乐于分享。&lt;/p&gt;

&lt;p&gt;如果下面提到的部分技术您不熟悉，也没有关系，因为可能是您还没有熟悉该技术的需求。成为同事后，我们一起在项目中熟悉。&lt;/p&gt;
&lt;h2 id="Ruby技术栈"&gt;Ruby 技术栈&lt;/h2&gt;
&lt;p&gt;Ruby 基础扎实，熟悉 Rails。
  Grape, Sinatra 和 RSpec 需要了解。&lt;/p&gt;
&lt;h2 id="JavaScript技术栈"&gt;JavaScript 技术栈&lt;/h2&gt;
&lt;p&gt;NodeJS&lt;/p&gt;
&lt;h2 id="其他技术栈"&gt;其他技术栈&lt;/h2&gt;
&lt;p&gt;Linux, Git, PostgreSQL, Redis 等。&lt;/p&gt;
&lt;h2 id="加分项"&gt;加分项&lt;/h2&gt;
&lt;p&gt;RubyMotion, Swift, Python, Lisp, Scala, MongoDB, Meteor, EmberJS, AngularJS, ionic, phoneGap, Cordova, React-native 等。
  安卓 Android APP 和苹果 iOS APP 开发经验。&lt;/p&gt;
&lt;h2 id="我们面临的挑战"&gt;我们面临的挑战&lt;/h2&gt;
&lt;p&gt;1 软件如何有效支持大并发网络环境？
  2 前后端程序，还有手机 APP 项目，需要投入人力。&lt;/p&gt;

&lt;p&gt;我们非常关注把优秀的技术用对地方，并关注代码质量。
在这里，每个同事都像兄弟一样相处。我们关心你技术的成长！&lt;/p&gt;
&lt;h2 id="薪资水平"&gt;薪资水平&lt;/h2&gt;
&lt;p&gt;薪资 10000 - 16000 元。这个薪资和上海等一线城市的确没法比，不过在苏州市场上还是有竞争力的（您可能不知道，苏州房价偏低，适合定居）。
如果您是技术上牛人，社区中的名人，薪资可以再加。&lt;/p&gt;

&lt;p&gt;我们是一个崇尚敏捷的团队，不提倡加班。自在双休。&lt;/p&gt;</description>
      <author>gazeldx</author>
      <pubDate>Wed, 24 Jun 2015 14:13:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/26156</link>
      <guid>https://ruby-china.org/topics/26156</guid>
    </item>
  </channel>
</rss>
