<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>yhuiche (鲁笔)</title>
    <link>https://ruby-china.org/yhuiche</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Rack 中间件简单理解及例子</title>
      <description>&lt;p&gt;&lt;a href="https://www.oswish.net/blogs/57a857a163b1d9604600000a" rel="nofollow" target="_blank" title=""&gt;此博客原文链接&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;注：这里是根据网上的常见的 rack 例子更改&lt;/p&gt;
&lt;h3 id="rack 版本"&gt;rack 版本&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Rack 为使用 Ruby 开发 web 应用提供了一个最小的模块化和可修改的接口。用可能最简单的方式来包装 HTTP 请求和响应，它为 web 服务器，web 框架和中间件的 API 进行了统一并提纯到了单一的方法调用。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;测试中 rack gem 版本为 1.6.4&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
&lt;h3 id="示例代码"&gt;示例代码&lt;/h3&gt;&lt;pre class="highlight ruby"&gt;&lt;code&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;A&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="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;# @app: Rack::B&lt;/span&gt;
      &lt;span class="vi"&gt;@header_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"X-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;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;start_time&lt;/span&gt; &lt;span class="o"&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="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="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;#  Rack::B 实例调用 call&lt;/span&gt;
      &lt;span class="n"&gt;request_time&lt;/span&gt; &lt;span class="o"&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="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_time&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;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@header_name&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="vi"&gt;@header_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"%0.6f"&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;request_time&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;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="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;B&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="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;# @app: Rack::C&lt;/span&gt;
      &lt;span class="vi"&gt;@header_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"X-test"&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;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="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;#  Rack::C 实例调用 call&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;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has_key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@header_name&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="vi"&gt;@header_name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'yyyyyy'&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;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="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'aaaaaa'&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;class&lt;/span&gt; &lt;span class="nc"&gt;C&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="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'text/plain'&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'hello world!'&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="n"&gt;use&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;A&lt;/span&gt;
&lt;span class="n"&gt;use&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;B&lt;/span&gt;

&lt;span class="n"&gt;run&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;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt; 为了探究中间件的加载运行过程，这里用 A、B、C 顺序来定义 class&lt;/li&gt;
&lt;li&gt; 实际运行的代码存在打印语句，后面有打印结果&lt;/li&gt;
&lt;li&gt; 其中 Rack::C 就相当于 Rails App&lt;/li&gt;
&lt;li&gt; A、B 则相当于中间件&lt;/li&gt;
&lt;li&gt; A、B、C 都为 rack app&lt;br&gt;
&lt;/li&gt;
&lt;li&gt; 通过实例变量&lt;a href="/app" class="user-mention" title="@app"&gt;&lt;i&gt;@&lt;/i&gt;app&lt;/a&gt;实现 rack app 一种嵌套结构&lt;/li&gt;
&lt;li&gt; 文件命名为 ~/test/config.ru&lt;/li&gt;
&lt;li&gt; call 方法统一返回格式，每次返回结果都会在内层返回的结果上做处理后返回结果给外层的调用&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
&lt;h3 id="运行打印结果"&gt;运行打印结果&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt; 运行命名下面名，然后用浏览器访问本地 9292 端口&lt;a href="http://localhost:9292" rel="nofollow" target="_blank"&gt;http://localhost:9292&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; cd ~/test&lt;/li&gt;
&lt;li&gt; rackup&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/test $ rackup

new B  -------------
@app: #&amp;lt;Rack::C:0x007fa4b2ad4298&amp;gt;
------------------------------
new A-------------
@app: #&amp;lt;Rack::B:0x007fa4b2ad41f8&amp;gt;
------------------------------

Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on localhost:9292, CTRL+C to stop

A call -------------
@app: #&amp;lt;Rack::B:0x007fa4b2ad41f8&amp;gt;
------------------------------
B call ----------------
@app: #&amp;lt;Rack::C:0x007fa4b2ad4298&amp;gt;
------------------------------
C call ----------
#&amp;lt;Rack::C:0x007fa4b2ad4298&amp;gt;
------------------------------
127.0.0.1 - - [08/Aug/2016:00:57:19 +0800] "GET / HTTP/1.1" 200 - 0.0041

A call -------------
@app: #&amp;lt;Rack::B:0x007fa4b2ad41f8&amp;gt;
------------------------------
B call ----------------
@app: #&amp;lt;Rack::C:0x007fa4b2ad4298&amp;gt;
------------------------------
C call ----------
#&amp;lt;Rack::C:0x007fa4b2ad4298&amp;gt;
------------------------------
127.0.0.1 - - [08/Aug/2016:00:57:20 +0800] "GET /favicon.ico HTTP/1.1" 200 - 0.0006
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt; 可以看到在 class Rack::A 中，&lt;a href="/app" class="user-mention" title="@app"&gt;&lt;i&gt;@&lt;/i&gt;app&lt;/a&gt;为 class Rack::B 的一个实例；而在 class Rack::B 中，&lt;a href="/app" class="user-mention" title="@app"&gt;&lt;i&gt;@&lt;/i&gt;app&lt;/a&gt;则为 Rack::C。&lt;/li&gt;
&lt;li&gt; 在接受到浏览器的访问后，调用了中间件的 call 方法，这里有点类似于递归的调法。从代码及返回结果可以看出，是 Rack::A 中的 call 方法先被调用，然后是 Rack::B 中的，最后是 Rack::C 中的。返回是顺序刚好相反，先是 Rack::C 中的 call 方法先执行完，然后是 Rack::B，最后是 Rack::A。&lt;/li&gt;
&lt;li&gt;这段日志有两个访问记录，一个是 &lt;a href="http://localhost:9292" rel="nofollow" target="_blank"&gt;http://localhost:9292&lt;/a&gt; 主体，一个是网站收藏图标 favicon.ico&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;
&lt;h3 id="浏览器查看到的部分数据"&gt;浏览器查看到的部分数据&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: text/plain
X-test: yyyyyy
X-A: 0.000032
Transfer-Encoding: chunked
Connection: close
Server: thin
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="浏览器页面看到的结果"&gt;浏览器页面看到的结果&lt;/h4&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;hello world!aaaaaa
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;这里看到的是浏览器中查看到了部分数据&lt;/li&gt;
&lt;li&gt;可以看出 rack 默认的 web 服务器是 thin&lt;/li&gt;
&lt;li&gt;X-text、X-A 为 call 方法中返回的部分数据&lt;/li&gt;
&lt;li&gt;页面看到的东西则为 call 方法中返回的 body 部分&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;hr&gt;</description>
      <author>yhuiche</author>
      <pubDate>Sat, 13 Aug 2016 17:25:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/30815</link>
      <guid>https://ruby-china.org/topics/30815</guid>
    </item>
    <item>
      <title>rails s 启动过程</title>
      <description>&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;命令&lt;/span&gt; &lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; 
    &lt;span class="n"&gt;windows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;这里会执行&lt;/span&gt; &lt;span class="no"&gt;RUBY_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bat&lt;/span&gt; &lt;span class="n"&gt;文件&lt;/span&gt;
             &lt;span class="n"&gt;之后将执行权交给&lt;/span&gt; &lt;span class="s1"&gt;'RUBY_PATH/bin/rails'&lt;/span&gt;

    &lt;span class="n"&gt;linux&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;这里会执行&lt;/span&gt; &lt;span class="s1"&gt;'RUBY_PATH/bin/rails'&lt;/span&gt;

    &lt;span class="n"&gt;跳转&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="no"&gt;RUBY_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;中&lt;/span&gt;
        &lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="no"&gt;Gem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bin_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'railties'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'rails'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;这里将跳转的railties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;目录中&lt;/span&gt; &lt;span class="s1"&gt;'RAILTIES_PATH/bin/rails'&lt;/span&gt;


&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;railties&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="no"&gt;RAILTIES_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt; &lt;span class="n"&gt;有&lt;/span&gt;
        &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"rails/cli"&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="n"&gt;文件后会执行文件代码&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;文件中class&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;module的代码其实只是定义作用&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;所以本文中并不是所有的require语句都会提示跳转&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;这里将跳转交到&lt;/span&gt; &lt;span class="s2"&gt;"RAILTIES_PATH/lib/rails/cli.rb"&lt;/span&gt;

    &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="no"&gt;RAILTIES_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;cli&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; &lt;span class="n"&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;ScriptRailsLoader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exec_script_rails!&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;这里将跳转交到&lt;/span&gt; &lt;span class="s1"&gt;'RAILTIES_PATH/lib/script_rails_loader.rb'&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;方法&lt;/span&gt; &lt;span class="s1"&gt;'exec_script_rails!'&lt;/span&gt;

    &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;script_rails_loader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="no"&gt;RAILTIES_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;script_rails_loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rb&lt;/span&gt; &lt;span class="n"&gt;中&lt;/span&gt;
    &lt;span class="n"&gt;调用方法&lt;/span&gt;   
        &lt;span class="n"&gt;exec_script_rails!&lt;/span&gt; 
    &lt;span class="n"&gt;其中的&lt;/span&gt;
        &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="no"&gt;RUBY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;SCRIPT_RAILS&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="no"&gt;ARGV&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;in_rails_application?&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里会跳转到rails项目(需要运行的rails项目) APP_ROOT_PATH/script/rails&lt;/span&gt;
        &lt;span class="c1"&gt;# exec 将以命令行的方式运行其接受的参数，并跳出当前脚本&lt;/span&gt;
        &lt;span class="c1"&gt;# RUBY 及 RUBY_PATH/bin/ruby&lt;/span&gt;
        &lt;span class="c1"&gt;# SCRIPT_RAILS 为 script/rails (注：'rails s'在APP所在目录执行)&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;这里会跳转到rails项目&lt;/span&gt; &lt;span class="s1"&gt;'APP_ROOT_PATH/script/rails'&lt;/span&gt;


&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="no"&gt;APP&lt;/span&gt;
    &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="s1"&gt;'APP_ROOT_PATH/script/rails'&lt;/span&gt; &lt;span class="n"&gt;中有&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="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;require&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/boot'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&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;# 设置了 APP_PATH&lt;/span&gt;
        &lt;span class="c1"&gt;# 加载 bundle &lt;/span&gt;
        &lt;span class="c1"&gt;# 跳转到  "RAILTIES_PATH/lib/rails/commands.rb"&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;跳转到&lt;/span&gt; &lt;span class="s2"&gt;"RAILTIES_PATH/lib/rails/commands.rb"&lt;/span&gt;


&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;RAILTIES_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;rails&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;commands&lt;/span&gt;
    &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="s2"&gt;"RAILTIES_PATH/lib/rails/commands.rb"&lt;/span&gt; &lt;span class="n"&gt;中&lt;/span&gt;
        &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'server'&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;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;'../../'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;unless&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;exists?&lt;/span&gt;&lt;span class="p"&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="s2"&gt;"config.ru"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

          &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'rails/commands/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;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="nf"&gt;tap&lt;/span&gt; &lt;span class="p"&gt;{&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="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="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;# Rails::Server 继承与 Rack::Server，这里(server.start)跳转到了rack&lt;/span&gt;
        &lt;span class="c1"&gt;# def tap&lt;/span&gt;
        &lt;span class="c1"&gt;#   yield self&lt;/span&gt;
        &lt;span class="c1"&gt;#   self&lt;/span&gt;
        &lt;span class="c1"&gt;# end &lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;跳转到&lt;/span&gt; &lt;span class="s1"&gt;'RAILTIES_PATH/lib/rails/commands/server.rb'&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="n"&gt;rack的一个子类&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&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;start&lt;/span&gt;


&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&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="n"&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;start&lt;/span&gt;
    &lt;span class="n"&gt;这里主要加载rack&lt;/span&gt; &lt;span class="n"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;中间件&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;&lt;span class="n"&gt;加载&lt;/span&gt; &lt;span class="no"&gt;APP_PATH&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;ru&lt;/span&gt; &lt;span class="n"&gt;文件&lt;/span&gt;&lt;span class="err"&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;Application&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;要启动的rails项目的&lt;/span&gt; &lt;span class="no"&gt;Application类&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;加载到rack&lt;/span&gt;
    &lt;span class="n"&gt;在&lt;/span&gt; &lt;span class="s1"&gt;'RAILTIES_PATH/lib/rails/commands/server.rb'&lt;/span&gt; &lt;span class="n"&gt;中&lt;/span&gt;
        &lt;span class="c1"&gt;# def start&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="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="c1"&gt;# Rails::Server 继承与 Rack::Server&lt;/span&gt;
        &lt;span class="c1"&gt;# a) wrapped_app 加载了APP::Application以及中间件&lt;/span&gt;
        &lt;span class="c1"&gt;# b) 这里 server 其实就是Webrick或者Thin等服务&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;wrapped_app&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;Application以及中间件&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="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;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="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="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:environment&lt;/span&gt;&lt;span class="p"&gt;]].&lt;/span&gt;&lt;span class="nf"&gt;reverse_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;middleware&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="n"&gt;middleware&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="nb"&gt;self&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&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;:call&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;middleware&lt;/span&gt;
            &lt;span class="n"&gt;klass&lt;/span&gt; &lt;span class="o"&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;shift&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;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;middleware&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;app&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里主要是中间件的加载过程。rack中，中间件的定义例如&lt;/span&gt;
        &lt;span class="c1"&gt;# class Runtime&lt;/span&gt;
        &lt;span class="c1"&gt;#     def initialize(app, name = nil)&lt;/span&gt;
        &lt;span class="c1"&gt;#       @app = app&lt;/span&gt;
        &lt;span class="c1"&gt;#       ....&lt;/span&gt;
        &lt;span class="c1"&gt;#     end&lt;/span&gt;
        &lt;span class="c1"&gt;#     def call(env)&lt;/span&gt;
        &lt;span class="c1"&gt;#       status, headers, body = @app.call(env)&lt;/span&gt;
        &lt;span class="c1"&gt;#       ...&lt;/span&gt;
        &lt;span class="c1"&gt;#       end&lt;/span&gt;
        &lt;span class="c1"&gt;#     ...&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里的 app 参数传进去的其实就是一个中间件或者 APP::Application。即中间件形成了一个嵌套的结构，这个结构在展开（调用call方法）的时候是跟方便的,&lt;/span&gt;

        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;app&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="o"&gt;...&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里options[:config]指向config.ru文件&lt;/span&gt;
        &lt;span class="c1"&gt;# 在 Rack::Builder.parse_file 中有&lt;/span&gt;
        &lt;span class="c1"&gt;# app = eval "Rack::Builder.new {\n" + cfgfile + "\n}.to_app",TOPLEVEL_BINDING, config, 0&lt;/span&gt;
        &lt;span class="c1"&gt;# cfgfile 为 config.ru文件 的具体类容&lt;/span&gt;
        &lt;span class="c1"&gt;# 在 Rack::Builder 中有&lt;/span&gt;
        &lt;span class="c1"&gt;# def initialize(default_app = nil,&amp;amp;block)&lt;/span&gt;
        &lt;span class="c1"&gt;#   @use, @map, @run = [], nil, default_app&lt;/span&gt;
        &lt;span class="c1"&gt;#   instance_eval(&amp;amp;block) if block_given?&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="c1"&gt;# def run(app)&lt;/span&gt;
        &lt;span class="c1"&gt;#   @run = app&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="c1"&gt;# 在config.ru中有&lt;/span&gt;
        &lt;span class="c1"&gt;# run APP::Application&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里就将APP::Application加载都了rack中&lt;/span&gt;

        &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;这里&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="n"&gt;其实就是Webrick或者Thin等服务&lt;/span&gt;
        &lt;span class="n"&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;server&lt;/span&gt;
          &lt;span class="vi"&gt;@_server&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;Handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&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;:server&lt;/span&gt;&lt;span class="p"&gt;])&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;Handler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;default&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="c1"&gt;# 跟踪在Rack::Handler中有&lt;/span&gt;
        &lt;span class="c1"&gt;# # def default&lt;/span&gt;
        &lt;span class="c1"&gt;# begin&lt;/span&gt;
        &lt;span class="c1"&gt;#   Rack::Handler::Thin&lt;/span&gt;
        &lt;span class="c1"&gt;# rescue LoadError&lt;/span&gt;
        &lt;span class="c1"&gt;#   Rack::Handler::WEBrick&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="c1"&gt;# rack 中缺省的服务选择的事Thin，但在rails中没有加载thin的gem，所以会使用webrick。如果要使用thin，在gemfile中添加thin的gem即可&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&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;Handler&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Thin&lt;/span&gt; &lt;span class="s1"&gt;'RACK_PATH/lib/rack/handler/thin.rb'&lt;/span&gt;&lt;span class="err"&gt;（&lt;/span&gt;&lt;span class="n"&gt;本文使用thin&lt;/span&gt;&lt;span class="err"&gt;），&lt;/span&gt;&lt;span class="n"&gt;执行方法run&lt;/span&gt;&lt;span class="err"&gt;，&lt;/span&gt;


&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&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;Handler&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Thin&lt;/span&gt; &lt;span class="n"&gt;执行方法run&lt;/span&gt;
    &lt;span class="n"&gt;在Rack&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Handler&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Thin中有&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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Thin&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;options&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:Host&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s1"&gt;'0.0.0.0'&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;:Port&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;8080&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;yield&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&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="c1"&gt;# 可以看到这里调用了::Thin::Server的方法new、start&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里 app 参数包含了APP::Application,以及中间件&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;这里会跳转到&lt;/span&gt; &lt;span class="no"&gt;Thin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server&lt;/span&gt; &lt;span class="s1"&gt;'THIN_PATH/lib/thin/server.rb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;执行方法new&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;


&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;Thin&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="n"&gt;执行方法new&lt;/span&gt;&lt;span class="err"&gt;、&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;
    &lt;span class="n"&gt;在Thin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Server中有&lt;/span&gt;
        &lt;span class="c1"&gt;# def initialize(*args, &amp;amp;block)&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;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;arg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
          &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;Fixnum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sr"&gt;/^\d+$/&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;          &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;
          &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;            &lt;span class="k"&gt;then&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;arg&lt;/span&gt;
          &lt;span class="k"&gt;else&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;arg&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;arg&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;:call&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="vi"&gt;@backend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;select_backend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&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;@backend.server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;

        &lt;span class="c1"&gt;# def start&lt;/span&gt;
        &lt;span class="vi"&gt;@backend.start&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;setup_signals&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@setup_signals&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;# 可以看做 @app 是上面（6）中传过来的参数，包含了APP::Application,以及中间件&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里将 Thin::Server的实例绑到了@backend中，及将app绑定到了@backend中&lt;/span&gt;
        &lt;span class="c1"&gt;# 跟踪 select_backend 有&lt;/span&gt;
        &lt;span class="c1"&gt;# Backends::TcpServer.new(host, port) # rails 启动时select_backend会返回该值&lt;/span&gt;
    &lt;span class="o"&gt;--&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;这里会跳转到&lt;/span&gt; &lt;span class="no"&gt;Backends&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TcpServer&lt;/span&gt; &lt;span class="s1"&gt;'THIN_PATH/lib/thin/backends/tcp_server.rb'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;执行start&lt;/span&gt;


&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;Backends&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TcpServer&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;执行start&lt;/span&gt;
    &lt;span class="no"&gt;Backends&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;TcpServer&lt;/span&gt; &lt;span class="n"&gt;继承了&lt;/span&gt; &lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Thin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Backends&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="n"&gt;在&lt;/span&gt; &lt;span class="no"&gt;Thin&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Backends&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;中有&lt;/span&gt;
        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;
          &lt;span class="vi"&gt;@stopping&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;starter&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
            &lt;span class="n"&gt;connect&lt;/span&gt;
            &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;block_given?&lt;/span&gt;
            &lt;span class="vi"&gt;@running&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="c1"&gt;# Allow for early run up of eventmachine.&lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;EventMachine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reactor_running?&lt;/span&gt;
            &lt;span class="n"&gt;starter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;
          &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="vi"&gt;@started_reactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
            &lt;span class="no"&gt;EventMachine&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;starter&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;def&lt;/span&gt; &lt;span class="nf"&gt;initialize_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backend&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;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;app&lt;/span&gt;                     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@server.app&lt;/span&gt;
          &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;comm_inactivity_timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@timeout&lt;/span&gt;
          &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;threaded&lt;/span&gt;                &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@threaded&lt;/span&gt;
          &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="k"&gt;end&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里调用了connect方法，该方法在Backends::TcpServer中有定义&lt;/span&gt;
        &lt;span class="c1"&gt;# def connect&lt;/span&gt;
        &lt;span class="c1"&gt;#   @signature = EventMachine.start_server(@host, @port, Connection, &amp;amp;method(:initialize_connection))&lt;/span&gt;
        &lt;span class="c1"&gt;# end&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里Connection是 Thin::Connection,'THIN_PATH/lib/thin/connection.rb'&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里生成了一个Connection实例，绑定了上面传过来的app。并将Connection实例传给了EventMachine&lt;/span&gt;
        &lt;span class="c1"&gt;# 这里可以看出，thin使用了 EventMachine,EventMachine是一个基于Reactor设计模式的、用于网络编程和并发编程的事件驱动框架。&lt;/span&gt;
        &lt;span class="c1"&gt;# 最后的启动交给了EventMachine，由EventMachine完成启动。&lt;/span&gt;
        &lt;span class="c1"&gt;# EventMachine比较底层了，可以对消息进行接收与回复，下面是一个例子&lt;/span&gt;


&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="no"&gt;EventMachine&lt;/span&gt; &lt;span class="n"&gt;例子&lt;/span&gt;
    &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'eventmachine'&lt;/span&gt;

    &lt;span class="no"&gt;Str&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;Eos&lt;/span&gt;&lt;span class="sh"&gt;
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
      &amp;lt;title&amp;gt;hello, eventmachine &amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1 style='color:#ff0000'&amp;gt;hello, eventmachine &amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;Eos&lt;/span&gt;
    &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Pass&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EventMachine&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Connection&lt;/span&gt;
      &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;receive_data&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;
        &lt;span class="n"&gt;send_data&lt;/span&gt; &lt;span class="no"&gt;Str&lt;/span&gt;
        &lt;span class="n"&gt;close_connection_after_writing&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;test&lt;/span&gt; &lt;span class="n"&gt;hh&lt;/span&gt;
      &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="mi"&gt;111111111111111&lt;/span&gt;
      &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;hh&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="no"&gt;EM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;EM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start_server&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'0.0.0.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;Pass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:test&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;# 这个例子可以通过浏览器访问 http://127.0.0.1:10001&lt;/span&gt;
    &lt;span class="c1"&gt;# 每次收到消息后，都会执行 receive_data&lt;/span&gt;
    &lt;span class="c1"&gt;# 由 send_data 回复信息&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;EventMachine 参考 &lt;a href="http://wonderflow.info/wp-content/uploads/2013/07/EventMachine%E5%85%A5%E9%97%A8.pdf" rel="nofollow" target="_blank"&gt;http://wonderflow.info/wp-content/uploads/2013/07/EventMachine%E5%85%A5%E9%97%A8.pdf&lt;/a&gt;&lt;/p&gt;</description>
      <author>yhuiche</author>
      <pubDate>Fri, 29 Aug 2014 21:00:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/21294</link>
      <guid>https://ruby-china.org/topics/21294</guid>
    </item>
    <item>
      <title>URL 中 %400 错误</title>
      <description>&lt;p&gt;在 url 如果存在%（此处不是 url 编码后产生的%），rails 在解析 url 时会抛出 error。这个问题有没有很好的解决方案。&lt;/p&gt;</description>
      <author>yhuiche</author>
      <pubDate>Mon, 28 Jul 2014 23:44:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/20724</link>
      <guid>https://ruby-china.org/topics/20724</guid>
    </item>
    <item>
      <title>json.erb 文件，用 ajax 访问返回值格式不对</title>
      <description>&lt;p&gt;json.erb 文件，用 ajax 访问返回值格式不对，返回的怎么是 text，而不是 json？&lt;/p&gt;</description>
      <author>yhuiche</author>
      <pubDate>Mon, 17 Feb 2014 11:15:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/17299</link>
      <guid>https://ruby-china.org/topics/17299</guid>
    </item>
    <item>
      <title>devise 用户锁定</title>
      <description>&lt;p&gt;最近在使用 devise，遇到了点问题，如何直接锁定一个用户，使之不能登陆。&lt;/p&gt;</description>
      <author>yhuiche</author>
      <pubDate>Wed, 22 Jan 2014 10:51:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/16921</link>
      <guid>https://ruby-china.org/topics/16921</guid>
    </item>
    <item>
      <title>Rails 如何将 HTML 转换成 PDF?</title>
      <description>&lt;p&gt;我在 rails 中使用 wkhtmltopdf 将 html 文件转换成 pdf 文件，能够很好地转换，但是发现有一两秒的生成时间，速度不够理想。有没有更加快速的方法？？&lt;/p&gt;</description>
      <author>yhuiche</author>
      <pubDate>Tue, 15 Oct 2013 16:41:08 +0800</pubDate>
      <link>https://ruby-china.org/topics/14769</link>
      <guid>https://ruby-china.org/topics/14769</guid>
    </item>
    <item>
      <title>ror+mongodb 中的中 filed 类型</title>
      <description>&lt;p&gt;我在做一个东西，用的是 ror+mongodb，其中一个 class 中有个 filed 的类型不确定，这个类型要根据初始化时传入的参数的类型而定。我弄晕了还是没搞定。。跪求各位救命啊啊啊。。。
本来打算用下面这个思路的，但是从数据库用出来后类型总是 Hash，而不是我要的类型。。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Abc&lt;/span&gt; 
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Mongoid&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Document&lt;/span&gt;
  &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="ss"&gt;:value&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;attrs&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;options&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;value_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Monetary'&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value_type&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt; &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&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;/code&gt;&lt;/pre&gt;</description>
      <author>yhuiche</author>
      <pubDate>Tue, 19 Feb 2013 17:25:12 +0800</pubDate>
      <link>https://ruby-china.org/topics/8775</link>
      <guid>https://ruby-china.org/topics/8775</guid>
    </item>
  </channel>
</rss>
