<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>wwwicbd (Baodong)</title>
    <link>https://ruby-china.org/wwwicbd</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>填字游戏</title>
      <description>&lt;h2 id="游戏规则:"&gt;游戏规则：&lt;/h2&gt;
&lt;p&gt;在每个 &lt;code&gt;[]&lt;/code&gt; 中填写序号，运行该脚本，如果输出的数字依次递增就算赢啦 🎉 ( 最多有两次调试机会 )&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;game.rb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_support/concern'&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;C&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="kp"&gt;extend&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;Concern&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;B&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="kp"&gt;extend&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;Concern&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;C&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="n"&gt;included&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;A&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;B&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;
&lt;span class="no"&gt;A&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;hello&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s1"&gt;'[]'&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 15 Feb 2019 14:00:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/38110</link>
      <guid>https://ruby-china.org/topics/38110</guid>
    </item>
    <item>
      <title>两个库的相同算法, hash 结果不一致的问题</title>
      <description>&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'digest'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'openssl'&lt;/span&gt;

&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'内容😝'&lt;/span&gt;
&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Digest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SHA1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;HMAC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;OpenSSL&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Digest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SHA1&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;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="cm"&gt;=begin
"5d968ccf64b6f17441c39d076f2fb53119cbeafc"
"d0d3ec791cee9b44a21338973729a080572a6e81"
=end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的 key 要怎么选才能得到相同的 hash 呢？
(其实问题的本质是不懂怎么看源码~)&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Mon, 16 Jul 2018 17:32:32 +0800</pubDate>
      <link>https://ruby-china.org/topics/37168</link>
      <guid>https://ruby-china.org/topics/37168</guid>
    </item>
    <item>
      <title>HTTP Condition Request on Rails</title>
      <description>&lt;h2 id="HTTP Condition Request"&gt;HTTP Condition Request&lt;/h2&gt;&lt;h3 id="概念回顾"&gt;概念回顾&lt;/h3&gt;
&lt;p&gt;所谓条件请求，就是 Server 根据请求头的条件的不同而返回不同的响应。&lt;/p&gt;

&lt;p&gt;这里所说的条件即验证器，有两种：&lt;/p&gt;

&lt;p&gt;最后修改时间 (last-modified) 和 内容指纹 (etag), 可以单独使用或者联合使用。&lt;/p&gt;

&lt;p&gt;验证的过程区分 &lt;code&gt;强验证&lt;/code&gt; 还是 &lt;code&gt;弱验证&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;强验证&lt;/code&gt; 要求内容完成相同。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;弱验证&lt;/code&gt; 只要求主体内容相同，允许部分片段有差异，具体规则自定义。&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;验证类型 x 验证器&lt;/th&gt;
&lt;th&gt;最后修改时间&lt;/th&gt;
&lt;th&gt;内容指纹&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;强验证&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;逐 bit 比较，要求完全相同&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;弱验证&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;内容主体相同，允许部分变化&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3 id="例子"&gt;例子&lt;/h3&gt;&lt;h4 id="第一次GET请求 2.json"&gt;第一次 GET 请求 2.json&lt;/h4&gt;
&lt;p&gt;Request 无特殊 Header.&lt;/p&gt;

&lt;p&gt;Response 返回内容的同时，在 Header 中设置了 &lt;code&gt;ETag&lt;/code&gt; 和 &lt;code&gt;Cache-Control&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/ff3d5229-3401-4b67-b39c-c815747b7ccf.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Cache-Control&lt;/code&gt; 中，&lt;/p&gt;

&lt;p&gt;&lt;code&gt;max-age=0&lt;/code&gt; 表示 0 秒后资源过期，也就是每次都要检查缓存，如果缓存还新鲜就用缓存.
 &lt;code&gt;no-cache&lt;/code&gt; 也要求很次都检查缓存，但强制要求重新请求，不使用缓存，即使缓存可用。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;private&lt;/code&gt; 表示仅允许 user-agent 缓存该请求，不允许代理服务器缓存.
 相对应的 &lt;code&gt;public&lt;/code&gt; 允许 user-agent 和代理服务器缓存该请求。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;must-revalidate&lt;/code&gt; 表示需要在使用缓存前校验缓存状态，不允许使用过期的缓存。&lt;/p&gt;
&lt;h4 id="第二次GET请求 2.json (内容没有修改)"&gt;第二次 GET 请求 2.json (内容没有修改)&lt;/h4&gt;
&lt;p&gt;Request 携带了上一次的 &lt;code&gt;ETag&lt;/code&gt; 值，放在 &lt;code&gt;If-None_Match&lt;/code&gt; 中。&lt;/p&gt;

&lt;p&gt;Response 取请求头中的内容指纹，跟准备返回的内容的指纹做比对，如果内容一致就响应 &lt;code&gt;304&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/60640164-4a2e-4688-8109-5f2a194c5f0d.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;指纹中 &lt;code&gt;W/&lt;/code&gt; 表示当前使用的是 弱验证，&lt;code&gt;W&lt;/code&gt; 大小写敏感。&lt;/p&gt;
&lt;h4 id="第三次GET请求 2.json (内容存在修改)"&gt;第三次 GET 请求 2.json (内容存在修改)&lt;/h4&gt;
&lt;p&gt;Request 依然携带上一次的 ETag 值。&lt;/p&gt;

&lt;p&gt;Response 判断内容有更新 (指纹不一致), 响应 &lt;code&gt;200&lt;/code&gt; , 发送新的内容。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/57ec3df1-7de5-4007-a26c-fc596497b743.png!large" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="Rails 的实现"&gt;Rails 的实现&lt;/h2&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# GET /products/1&lt;/span&gt;
&lt;span class="c1"&gt;# GET /products/1.json&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;刚才 GET 请求对应的 show 方法如上，也就是说这些处理过程都是自动完成的 :)  &lt;/p&gt;

&lt;p&gt;正常的处理完成，并且是 &lt;code&gt;200&lt;/code&gt; 或 &lt;code&gt;201&lt;/code&gt; 的响应，并且需要检查缓存时，
Rack 计算 body 的 SHA256, 设置 &lt;code&gt;ETag&lt;/code&gt; 和 &lt;code&gt;Cache-Control&lt;/code&gt; .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;rack/etag&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;skip_caching?&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="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="no"&gt;CACHE_CONTROL&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;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;CACHE_CONTROL&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'no-cache'&lt;/span&gt;&lt;span class="p"&gt;))&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;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ETAG_STRING&lt;/span&gt;&lt;span class="p"&gt;)&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;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Last-Modified'&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;digest_body&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="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="n"&gt;digest&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;body&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;part&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;parts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;Digest&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;SHA256&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="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;part&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;part&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;end&lt;/span&gt;

  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hexdigest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;byteslice&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;32&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;默认的验证规则实际上是强验证，因为此时并没有定义弱验证规则，是对 body 整体的 hash.&lt;/p&gt;

&lt;p&gt;如果我们需要自定义弱验证规则，可以使用 Rails 的 &lt;code&gt;stale?&lt;/code&gt; 和 &lt;code&gt;fresh_when&lt;/code&gt; .&lt;/p&gt;
&lt;h3 id="例子"&gt;例子&lt;/h3&gt;
&lt;p&gt;例如 product 的 GET 请求，如果我们定义只有产品的价格有变化才算是有效变化，其他变化都可以忽略。&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;show&lt;/span&gt;
  &lt;span class="n"&gt;fresh_when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@product.price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;只修改 product 描述的时候，server 响应 &lt;code&gt;304&lt;/code&gt;, 浏览器依然使用旧的缓存;
 修改价格后，响应 &lt;code&gt;200&lt;/code&gt; 并返回新的内容。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;actionpack-5.1.6/lib/action_controller/metal/conditional_get.rb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fresh_when&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&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="ss"&gt;etag: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;weak_etag: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;strong_etag: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;last_modified: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;public: &lt;/span&gt;&lt;span class="kp"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;template: &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;weak_etag&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;etag&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;strong_etag&lt;/span&gt;
      &lt;span class="n"&gt;last_modified&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="n"&gt;object&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;:updated_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;object&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;:maximum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:updated_at&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;strong_etag&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;strong_etag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;combine_etags&lt;/span&gt; &lt;span class="n"&gt;strong_etag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;last_modified: &lt;/span&gt;&lt;span class="n"&gt;last_modified&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;public: &lt;/span&gt;&lt;span class="kp"&gt;public&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;template: &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;
      &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;weak_etag&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;template&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;weak_etag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;combine_etags&lt;/span&gt; &lt;span class="n"&gt;weak_etag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="ss"&gt;last_modified: &lt;/span&gt;&lt;span class="n"&gt;last_modified&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;public: &lt;/span&gt;&lt;span class="kp"&gt;public&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;template: &lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;
      &lt;span class="k"&gt;end&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;last_modified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;last_modified&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;last_modified&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;cache_control&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:public&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;if&lt;/span&gt; &lt;span class="kp"&gt;public&lt;/span&gt;

      &lt;span class="n"&gt;head&lt;/span&gt; &lt;span class="ss"&gt;:not_modified&lt;/span&gt; &lt;span class="k"&gt;if&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;fresh?&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="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这个例子中，object 是 &lt;code&gt;@product.price&lt;/code&gt;, 它没有 &lt;code&gt;updated_at&lt;/code&gt; 方法，Server 便不会设置 &lt;code&gt;Last-Modified&lt;/code&gt; 头。&lt;/p&gt;

&lt;p&gt;浏览器收不到 &lt;code&gt;Last-Modified&lt;/code&gt; 就不会在下一次 GET 请求中携带 &lt;code&gt;If-Modified-Since&lt;/code&gt;, 也就是说这种情况下，只通过内容指纹进行验证。&lt;/p&gt;

&lt;p&gt;如果 object 有 &lt;code&gt;updated_at&lt;/code&gt; 方法，Server 会自动设置 &lt;code&gt;Last-Modified&lt;/code&gt; .&lt;/p&gt;

&lt;p&gt;当然也可以手动设置，如 &lt;code&gt;fresh_when(@product.price, last_modified: Time.now)&lt;/code&gt; ,这样也会令每次的缓存都失效。&lt;/p&gt;

&lt;p&gt;还可以把 etag 声明到控制器中：&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;ProductsController&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;# sth...&lt;/span&gt;
  &lt;span class="n"&gt;etag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="vi"&gt;@product.try&lt;/span&gt; &lt;span class="ss"&gt;:price&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;show&lt;/span&gt;
    &lt;span class="n"&gt;fresh_when&lt;/span&gt; &lt;span class="vi"&gt;@product&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="c1"&gt;# sth...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;需要注意的是在方法中仍要使用 &lt;code&gt;fresh_when&lt;/code&gt; 或 &lt;code&gt;stale?&lt;/code&gt; ,否则使用默认的策略。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;actionpack-5.1.6/lib/action_controller/metal/conditional_get.rb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;etag&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;etagger&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;etaggers&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;etagger&lt;/span&gt;&lt;span class="p"&gt;]&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;combine_etags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;validator&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;etaggers&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;etagger&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;instance_exec&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;etagger&lt;/span&gt;&lt;span class="p"&gt;)&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;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="拓展阅读"&gt;拓展阅读&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Conditional_requests" rel="nofollow" target="_blank" title=""&gt;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Conditional_requests&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/1046966/whats-the-difference-between-cache-control-max-age-0-and-no-cache" rel="nofollow" target="_blank" title=""&gt;https://stackoverflow.com/questions/1046966/whats-the-difference-between-cache-control-max-age-0-and-no-cache&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control" rel="nofollow" target="_blank" title=""&gt;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/ETag" rel="nofollow" target="_blank" title=""&gt;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/ETag&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ruby-china.github.io/rails-guides/caching_with_rails.html#conditional-get-support" rel="nofollow" target="_blank" title=""&gt;https://ruby-china.github.io/rails-guides/caching_with_rails.html#conditional-get-support&lt;/a&gt;&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Sun, 24 Jun 2018 17:14:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/37040</link>
      <guid>https://ruby-china.org/topics/37040</guid>
    </item>
    <item>
      <title>extract_options! 实现的疑问</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;active_support/core_ext/array/extract_options.rb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hash&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extractable_options?&lt;/span&gt;
    &lt;span class="nb"&gt;instance_of?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Hash&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;Array&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_options!&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;last&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;Hash&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;last&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extractable_options?&lt;/span&gt;
      &lt;span class="n"&gt;pop&lt;/span&gt;
    &lt;span class="k"&gt;else&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;h2 id="疑问:"&gt;疑问：&lt;/h2&gt;
&lt;p&gt;在 &lt;code&gt;extract_options!&lt;/code&gt; 中为啥要先判断 &lt;code&gt;is_a?&lt;/code&gt; 再判断 &lt;code&gt;instance_of?&lt;/code&gt; 呢？
我的理解是后者约束条件更强，没必要使用 &lt;code&gt;is_a?&lt;/code&gt; 方法吧。&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;H&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Hash&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;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;H&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;:hello&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt; &lt;span class="no"&gt;H&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_of?&lt;/span&gt; &lt;span class="no"&gt;H&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_of?&lt;/span&gt; &lt;span class="no"&gt;Hash&lt;/span&gt;

&lt;span class="cm"&gt;=begin
true
true
true
false
=end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Sat, 16 Jun 2018 11:46:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/36957</link>
      <guid>https://ruby-china.org/topics/36957</guid>
    </item>
    <item>
      <title>面试中的基础题小结</title>
      <description>&lt;p&gt;完成跟之前老板的深情告白之后，终于能重新出发 来写可爱的 Ruby 啦 🎉&lt;/p&gt;

&lt;p&gt;这个脚本是我准备面试前写的，罗列了一些可能会考的基础问题。(押题命中率还挺高的，示例代码不是对问题的直接回答，仅用于启发思路.)
还在求职的小伙伴可以参考一下，是不是每个问题都心中有数了。&lt;/p&gt;

&lt;p&gt;这周已经收到理想的 offer, 希望这个小结能对其他小伙伴也有帮助 :)&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"----------"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Enumerable 的遍历"&lt;/span&gt;
&lt;span class="cm"&gt;=begin
each 和 map 有什么区别?
带!和不带!的方法有什么约定?
使用 {} 和 do end 有什么区别?
=end&lt;/span&gt;

&lt;span class="n"&gt;fruits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"banana"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"pear"&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;"each: 循环遍历, 返回原数组"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&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;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&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;"map: 循环遍历, 将处理结果打包新数组返回"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&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;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&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;:upcase&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;"select: 返回数组, 筛选所有满足length&amp;gt;4的值"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&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;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&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;"reject: 返回数组, 筛选所有不满足length&amp;gt;4的值"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&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;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&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;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&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;"partition: 返回一个数组, 满足条件的包装起来放0位, 不满足的包装起来放1位"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;partition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&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;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&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;"find: 返回第一个满足条件的元素"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&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;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&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;"all?: 集合每个元素是否全都满足条件"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&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="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&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;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&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;"any?: 集合中是否存在一个满足条件的元素"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;f&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;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&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;"origin array:"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;fruits&lt;/span&gt;




&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"-----------"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Proc 与 lambda"&lt;/span&gt;
&lt;span class="cm"&gt;=begin
Proc 和 lambda 分别是什么? 使用时有什么区别?
Proc 的 lambda 的return怎么用? next怎么用?
yield 怎么用?
self 怎么用?
&amp;amp; 符号在形参和实参中分别代表什么意义?
=end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&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;from&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;to&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;num&lt;/span&gt;&lt;span class="o"&gt;|&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;sum&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;num&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;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;num&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;sum&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;total2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to&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;sum&lt;/span&gt; &lt;span class="o"&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;from&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;to&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;num&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;block&lt;/span&gt;
      &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&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;num&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;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;num&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;sum&lt;/span&gt;
&lt;span class="k"&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="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;total1&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;10&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;n&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="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="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"---"&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;total2&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;10&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;n&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="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="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"---"&lt;/span&gt;
&lt;span class="nb"&gt;proc&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="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="n"&gt;n&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="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="nb"&gt;p&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;total2&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;10&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;proc&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;"---"&lt;/span&gt;
&lt;span class="n"&gt;lambd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;lambda&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="n"&gt;n&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="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="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;lambd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;total2&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;10&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;lambd&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;"----------"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"alias 与 alias_method"&lt;/span&gt;
&lt;span class="cm"&gt;=begin
他们分别是什么? 使用时有什么区别?
https://blog.bigbinary.com/2012/01/08/alias-vs-alias-method.html
=end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hello&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s2"&gt;"say Hello"&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;say_alias&lt;/span&gt; &lt;span class="n"&gt;say&lt;/span&gt;
  &lt;span class="kp"&gt;alias_method&lt;/span&gt; &lt;span class="ss"&gt;:say_alias_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:say&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Hello&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;say&lt;/span&gt;
&lt;span class="no"&gt;Hello&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;say_alias&lt;/span&gt;
&lt;span class="no"&gt;Hello&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;say_alias_method&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hi&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s2"&gt;"Say Hi."&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;generate_alias&lt;/span&gt;
    &lt;span class="k"&gt;alias&lt;/span&gt; &lt;span class="n"&gt;say_alias&lt;/span&gt; &lt;span class="n"&gt;say&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;generate_alias_method&lt;/span&gt;
    &lt;span class="kp"&gt;alias_method&lt;/span&gt; &lt;span class="ss"&gt;:say_alias_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:say&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;Hi2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Hi&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;say&lt;/span&gt;
    &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="s2"&gt;"Say Hi !!!!!!!!!!!!!!!!!!"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

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

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'----'&lt;/span&gt;
&lt;span class="no"&gt;Hi2&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;say&lt;/span&gt;
&lt;span class="no"&gt;Hi2&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;say_alias&lt;/span&gt;
&lt;span class="no"&gt;Hi2&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;say_alias_method&lt;/span&gt;




&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"-----------"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"算法基础"&lt;/span&gt;
&lt;span class="cm"&gt;=begin
手工实现各种简单排序: 冒泡/插入/选择/归并/快排
分析各个实现的算法的时间复杂度和空间复杂度
在有先验条件的情况下该选哪种算法
=end&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;

  &lt;span class="c1"&gt;# 冒泡排序 O(n^2)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bubble_sort!&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;length&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="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;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;last_index&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;length&lt;/span&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="n"&gt;time&lt;/span&gt;
      &lt;span class="n"&gt;bubble_once!&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;last_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;span class="c1"&gt;# [i,j] 执行一次冒泡&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;bubble_once!&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;time&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;i&lt;/span&gt;
    &lt;span class="n"&gt;time&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="k"&gt;if&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;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;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;i&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="nb"&gt;self&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="nb"&gt;self&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;1&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="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;1&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;i&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;i&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="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="ss"&gt;:bubble_once!&lt;/span&gt;


  &lt;span class="c1"&gt;# 选择排序 O(n^2)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_sort!&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;length&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="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;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;last_index&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;length&lt;/span&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="n"&gt;time&lt;/span&gt;
      &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max_of_array&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;last_index&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;max_index&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;last_index&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="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;last_index&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;max_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;span class="c1"&gt;# [i,j] 最大的元素&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;max_of_array&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;max&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="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;max_index&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="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="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;index&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;if&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;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
        &lt;span class="n"&gt;max&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="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;max_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;
      &lt;span class="k"&gt;end&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;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="ss"&gt;:max_of_array&lt;/span&gt;


  &lt;span class="c1"&gt;# 插入排序 O(n^2)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;insert_sort!&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;length&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="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;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;insert_once!&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;time&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="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# 对于 [i,j] 将 self[j] 插入到合适的位置&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;insert_once!&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;number&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="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;
      &lt;span class="k"&gt;if&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;cursor&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;cursor&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="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cursor&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;cursor&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="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="n"&gt;cursor&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="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;cursor&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;cursor&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="k"&gt;end&lt;/span&gt;

  &lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="ss"&gt;:insert_once!&lt;/span&gt;


  &lt;span class="c1"&gt;# 归并排序 O(nlogn)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;merge_sort&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="n"&gt;size&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;left&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;/&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;right&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="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;/&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;size&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&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;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge_sort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge_sort&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="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;until&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;empty?&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;left&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;right&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;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;shift&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;right&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;ans&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;smaller&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;ans&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;


  &lt;span class="c1"&gt;# 快排 O(nlogn)&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;quick_sort&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="k"&gt;if&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;empty?&lt;/span&gt;

    &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rest&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;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;partition&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ele&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;ele&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quick_sort&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quick_sort&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&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="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"基本设计模式"&lt;/span&gt;
&lt;span class="cm"&gt;=begin
常用设计模式举例, 分别有什么典型应用?
=end&lt;/span&gt;

&lt;span class="c1"&gt;# 工厂模式&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CashBase&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"need implement"&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;Cash&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;CashBase&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total&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="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;n&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;CashVip&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;CashBase&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;rebate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@rebate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rebate&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;total&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="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="vi"&gt;@rebate&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;CashFactory&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;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&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;type&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"cash"&lt;/span&gt;
        &lt;span class="no"&gt;Cash&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;when&lt;/span&gt; &lt;span class="s2"&gt;"vip1"&lt;/span&gt;
        &lt;span class="no"&gt;CashVip&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="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s2"&gt;"vip2"&lt;/span&gt;
        &lt;span class="no"&gt;CashVip&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="mf"&gt;0.7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="no"&gt;Cash&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;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="no"&gt;CashFactory&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'cash'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;CashFactory&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'vip1'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;CashFactory&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'vip2'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;total&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 原型模式&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WorkEx&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:time_area&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:company&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"time_area:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;time_area&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;company:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;company&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="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Resume&lt;/span&gt;
  &lt;span class="nb"&gt;attr_accessor&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;:sex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:age&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:workex&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="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;
    &lt;span class="vi"&gt;@workex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;WorkEx&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;def&lt;/span&gt; &lt;span class="nf"&gt;set_person_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@sex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sex&lt;/span&gt;
    &lt;span class="vi"&gt;@age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&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;set_workex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time_area&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;company&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@workex.time_area&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time_area&lt;/span&gt;
    &lt;span class="vi"&gt;@workex.company&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;company&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;print&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"name: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;age:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt;sex:&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;sex&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="vi"&gt;@workex.print&lt;/span&gt;
    &lt;span class="nb"&gt;puts&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;self_clone&lt;/span&gt;
    &lt;span class="c1"&gt;# deep clone&lt;/span&gt;
    &lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Marshal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&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;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;no1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Resume&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="s2"&gt;"XiaoMing"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;no1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_person_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"man"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;no1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_workex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2017"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Google"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;no2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;no1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;self_clone&lt;/span&gt;
&lt;span class="n"&gt;no2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_workex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2018'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"facebook"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;no1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;
&lt;span class="n"&gt;no2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;


&lt;span class="c1"&gt;# Singleton&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'singleton'&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Logge&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Singleton&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;msg&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;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Logge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance&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;msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hhh"&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;"----------"&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"元编程"&lt;/span&gt;
&lt;span class="cm"&gt;=begin
Ruby 对象和类的关系, 画图解释一下?
继承和mixin的理解?
反射的使用?
打开类的使用?
=end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 27 Apr 2018 11:10:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/36078</link>
      <guid>https://ruby-china.org/topics/36078</guid>
    </item>
    <item>
      <title>Bootstrap 4  的 button  按钮防抖?</title>
      <description>&lt;p&gt;Rails5 with Bootstrap4, &lt;/p&gt;

&lt;p&gt;点击按钮去请求一个耗时的同步操作，给用户 UI 提示，并禁止他在此期间有意或者无意的重复点击。&lt;/p&gt;

&lt;p&gt;查到 button_to 里有 &lt;code&gt;disable_with&lt;/code&gt; 的选项，很好用，但是不知道怎么在 &lt;code&gt;disable_with&lt;/code&gt; 中添加复杂元素。&lt;/p&gt;
&lt;h3 id="问题1:"&gt;问题 1:&lt;/h3&gt;
&lt;p&gt;如何将图片和 JS 操作用于 &lt;code&gt;disable_with&lt;/code&gt; ?&lt;/p&gt;

&lt;p&gt;Bootstrap 有 &lt;code&gt;disabled&lt;/code&gt; 类，也支持 &lt;code&gt;disabled&lt;/code&gt; 属性.
当使用  &lt;code&gt;$(this).attr("disabled", "disabled");&lt;/code&gt; 发现后端收不到请求了，等待期间重复点击也收不到请求.
当使用 &lt;code&gt;$(this).addClass("disabled");&lt;/code&gt; 可以收到请求，但等待期间重复点击也会收到重复请求。&lt;/p&gt;
&lt;h3 id="问题2:"&gt;问题 2:&lt;/h3&gt;
&lt;p&gt;禁止提交重复请求该如何写 JS 的绑定事件？&lt;/p&gt;

&lt;p&gt;目前我的解决办法是：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;%= button_to containers_path,
                    method: :post,
                    class: "btn btn-block btn-outline-primary",
                    id: "create_tube",
                    remote: true do %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$(function () {
        $("#create_tube").click(function () {
            if ($(this).hasClass("disabled")) {
                $(this).attr("disabled", "disabled");
            } else {
                $("#create_tube .fa-plus").addClass("fa-pulse");
                $(this).addClass("disabled");
            }
        });
    });
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完成之后再分别重置 &lt;code&gt;disabled&lt;/code&gt; 的类和属性。
请问大家有更好的方法吗？谢谢&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Sun, 15 Apr 2018 23:41:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/35457</link>
      <guid>https://ruby-china.org/topics/35457</guid>
    </item>
    <item>
      <title>define_singleton_method 时调用自身原来方法</title>
      <description>&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"focus"&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;

&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_singleton_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:upcase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="s2"&gt;"singleton:"&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;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:upcase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;singleton_methods&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;

&lt;span class="c1"&gt;# "FOCUS"&lt;/span&gt;
&lt;span class="c1"&gt;# [:upcase]&lt;/span&gt;
&lt;span class="c1"&gt;# q.rb:6:in `block in &amp;lt;main&amp;gt;': stack level too deep (SystemStackError)&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;# from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;# from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;# ... 4355 levels...&lt;/span&gt;
&lt;span class="c1"&gt;#     from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;#         from q.rb:6:in `block in &amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;span class="c1"&gt;# from q.rb:10:in `&amp;lt;main&amp;gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="问题 1:"&gt;问题 1:&lt;/h2&gt;
&lt;p&gt;如上，如果想在 define_singleton_method 中使用对象原来的方法 (例子中的 upcase 方法), 要怎么做呢？&lt;/p&gt;
&lt;h2 id="问题 2:"&gt;问题 2:&lt;/h2&gt;
&lt;p&gt;如果在祖先链上有许多同名方法，怎么才能调用具体某个类下的那个方法呢？ (或者中某个类开始向前查找)&lt;/p&gt;

&lt;p&gt;谢谢&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 13 Apr 2018 13:40:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/35437</link>
      <guid>https://ruby-china.org/topics/35437</guid>
    </item>
    <item>
      <title>CentOS VirtualBox 网卡配置疑问</title>
      <description>&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ip addr
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: enp0s3: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:9b:a9:5d brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
       valid_lft 82686sec preferred_lft 82686sec
    inet6 fe80::e67d:e2cc:d14:4429/64 scope link
       valid_lft forever preferred_lft forever
3: enp0s8: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 08:00:27:23:b0:82 brd ff:ff:ff:ff:ff:ff
    inet 192.168.56.101/24 brd 192.168.56.255 scope global dynamic enp0s8
       valid_lft 1127sec preferred_lft 1127sec
    inet6 fe80::419d:8702:9ff5:ee50/64 scope link
       valid_lft forever preferred_lft forever

# service network status
Configured devices:
lo enp0s3
Currently active devices:
lo enp0s3 enp0s8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;centos7, 在 virtualBox 里开了 NAT 和 Host-only Adapter&lt;/p&gt;
&lt;h3 id="问题:"&gt;问题：&lt;/h3&gt;
&lt;p&gt;/etc/sysconfig/network-scripts 下面只有 ifcfg-enp0s3 没有 ifcfg-enp0s8 , 但是 enp0s8 目前是可用的，这是怎么回事？&lt;/p&gt;

&lt;p&gt;是否需要添加 enp0s8 的配置文件？官方文档说这个目录下的配置不建议手动修改，那么要通过哪个工具呢？&lt;/p&gt;

&lt;p&gt;Ubuntu 的 /etc/network/interfaces 在 centos7 下对应的是哪个配置？&lt;/p&gt;

&lt;p&gt;谢谢&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Wed, 11 Oct 2017 11:28:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/34350</link>
      <guid>https://ruby-china.org/topics/34350</guid>
    </item>
    <item>
      <title>{} 与 do end 的区别?</title>
      <description>&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n = 0
p Array.new(3) { n += 1 }

p Array.new(3) do
  n += 1
end

__END__
[1, 2, 3]
[nil, nil, nil]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;{} 和 do end 的结果不同，该如何解释呢？&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 29 Sep 2017 15:45:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/34293</link>
      <guid>https://ruby-china.org/topics/34293</guid>
    </item>
    <item>
      <title>[笔记] 处理 socket  的六种模型</title>
      <description>&lt;p&gt;以下是读 Jesse Storimer 两本书的笔记摘要，整理了处理 socket  的六种模型。&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;readme.md&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="thin_ftp"&gt;thin_ftp&lt;/h2&gt;
&lt;p&gt;一个 FTP Server Demo, 仅用于练习 Socket 编程。&lt;/p&gt;

&lt;p&gt;启动服务后 server 监听 21 端口，用于命令传输。&lt;/p&gt;

&lt;p&gt;文件传输采用 FTP 主动模式，client 发送 &lt;code&gt;PORT ip1,ip2,ip3,ip4,port1,port2&lt;/code&gt; 格式的数据，由 server 主动向其发起请求，用于文件传输。&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FTP::ProtocolHandler&lt;/code&gt; 负责具体的协议处理，&lt;code&gt;FTP::Serial&lt;/code&gt; 等负责 socket 处理。&lt;/p&gt;
&lt;h3 id="启动服务器"&gt;启动服务器&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ruby main.rb
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="使用ftp客户端"&gt;使用 ftp 客户端&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ftp -a -v 127.0.0.1 3000
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="Step1 FTP::Serial"&gt;Step1 FTP::Serial&lt;/h2&gt;
&lt;p&gt;串行执行。同时只能处理一个请求。&lt;/p&gt;
&lt;h2 id="Step2 FTP::MultiProcess"&gt;Step2 FTP::MultiProcess&lt;/h2&gt;
&lt;p&gt;父进程接受请求，将每个请求交由一个新的子进程处理，子进程处理完成后即销毁，把资源返还给系统.
可以同时处理多个请求，每个请求都有进程级别的隔离，互不干扰。但是衍生子进程又贵又慢。&lt;/p&gt;
&lt;h2 id="Step3 FTP::MultiThread"&gt;Step3 FTP::MultiThread&lt;/h2&gt;
&lt;p&gt;主线程接受请求，将每个请求交由一个新的线程处理，子线程处理完成后即销毁，把资源返还给系统.
可以同时处理多个请求，每个请求之间共享进程内存。用 &lt;code&gt;Connection&lt;/code&gt; 对象实例级别的隔离.
相比衍生新的进程要便宜许多，但还是受资源限制，过高的并发会令服务崩溃。&lt;/p&gt;
&lt;h2 id="Step4 FTP::ProcessPool"&gt;Step4 FTP::ProcessPool&lt;/h2&gt;
&lt;p&gt;为了限制 &lt;code&gt;MultiProcess&lt;/code&gt; 模式子进程的数量，提高处理新请求的响应速度，
本模式预先衍生出一定数量的子进程 (prefork), 是 &lt;code&gt;Serial&lt;/code&gt; 模式的多开版本.
主进程负责子进程池的填充/销毁/维护，具体的请求处理在子进程中进行.
新请求分配给哪个子进程处理的问题由系统内核负责。&lt;/p&gt;
&lt;h2 id="Step5 FTP::ThreadPool"&gt;Step5 FTP::ThreadPool&lt;/h2&gt;
&lt;p&gt;使用线程池代替进程池以节省开销。注意请求以 &lt;code&gt;Connection&lt;/code&gt; 的实例对象作为隔离.
主线程只负责填充线程池，完成后令其 sleep .&lt;/p&gt;
&lt;h2 id="Step6 FTP::Reactor"&gt;Step6 FTP::Reactor&lt;/h2&gt;
&lt;p&gt;反应器模式，将大块读写操作切碎然后非阻塞执行.
请求以 &lt;code&gt;Connection&lt;/code&gt; 的实例对象作为隔离，对象内保有其散碎的数据.
所有 socket 对象 以其文件描述符为 key , socket 对象本身为 value, 存储在 &lt;code&gt;@handlers&lt;/code&gt; 这个中央连接复用器中 (Hash).
事件分发器 (主循环) 使用 &lt;code&gt;select&lt;/code&gt; 系统调用，非阻塞地处理读写。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;详细内容请参考： &lt;a href="https://www.jstorimer.com/pages/books" rel="nofollow" target="_blank" title=""&gt;https://www.jstorimer.com/pages/books&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 08 Sep 2017 10:50:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/34062</link>
      <guid>https://ruby-china.org/topics/34062</guid>
    </item>
    <item>
      <title>像 PHP 的 die 方法一样终结 Rails 的 render</title>
      <description>&lt;h2 id="场景是这样的:"&gt;场景是这样的：&lt;/h2&gt;
&lt;p&gt;Redis 中用 String 型存了用户登录令牌，key 是令牌，value 是该用户的 ID.
定义一个 auth 方法，如果根据令牌能读到合法的用户 ID, 就意味着该令牌有效而且能获取 ID.(敏感权限再去数据库验证身份)&lt;/p&gt;

&lt;p&gt;在一部分接口中需要登录才能操作，所以希望一旦令牌非法，auth 方法直接 render 错误码然后终结后续操作.
这个场景在 PHP 中可以用 &lt;code&gt;die("err_info");&lt;/code&gt; 来处理。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog.arkency.com/2014/07/4-ways-to-early-return-from-a-rails-controller/" rel="nofollow" target="_blank" title=""&gt;4-ways-to-early-return-from-a-rails-controller&lt;/a&gt;
这篇文章提到了几个实用方法，利用返回值和 return 的组合.
但我想要的是一旦触发某个条件，无论是在 Controller 还是在某个方法里，立即 render 结果并终结后续操作。&lt;/p&gt;
&lt;h2 id="方案"&gt;方案&lt;/h2&gt;
&lt;p&gt;利用异常。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module DiyExceptions
  class RenderAndDie &amp;lt; StandardError
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::API
  # sth...

    # 类比PHP die()
  rescue_from DiyExceptions::RenderAndDie do |ex|
    msg = JSON(ex.message) rescue [1, "RenderAndDie"]
    resp = {
        code: msg[0],
        info: msg[1]
    }
    render json: resp
    logger.debug "&amp;gt;&amp;gt;&amp;gt;\n#{resp.to_json}&amp;lt;&amp;lt;&amp;lt;\n"
  end


  # 完全成功的请求
  # 直接结束请求
  def success(info)
    info = JSON.parse(info) rescue info if info.instance_of?(String)
    raise DiyExceptions::RenderAndDie, [0, info].to_json
  end


  # 业务上失败的请求, code &amp;gt; 0
  # 直接结束请求
  def failed(code, info)
    info = JSON.parse(info) rescue info if info.instance_of?(String)
    raise DiyExceptions::RenderAndDie, [code, info].to_json
  end

  # sth...
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如此，使用 failed 或 success 方法就可以啦 ;)&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;success "操作成功"

success [1,2,3]

success render_to_string json: {list: posts_list, total: posts_total}, include: {:user =&amp;gt; {only: [:id, :name, :avatar]}}
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Wed, 09 Aug 2017 12:01:06 +0800</pubDate>
      <link>https://ruby-china.org/topics/33779</link>
      <guid>https://ruby-china.org/topics/33779</guid>
    </item>
    <item>
      <title>联表查询写法的疑问</title>
      <description>&lt;p&gt;channel 有许多 post, post 属于某个 channel.
现在想查 post 数最多的 channel , sql 如下。&lt;/p&gt;

&lt;p&gt;请问 如果不用 find_by_sql 要怎么写这个查询呢？谢谢啦&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
    channels.*, count_t.p_count
FROM
    channels ,
    (
        SELECT
            channel_id ,
            count(posts.id) AS p_count
        FROM
            posts
        GROUP BY
            posts.channel_id
        ORDER BY
            p_count DESC
        LIMIT 10 OFFSET 0
    ) AS count_t
WHERE
    channels.id = count_t.channel_id
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 23 Jun 2017 11:33:45 +0800</pubDate>
      <link>https://ruby-china.org/topics/33296</link>
      <guid>https://ruby-china.org/topics/33296</guid>
    </item>
    <item>
      <title>关于集成测试与 helper 中的实例变量的疑问</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;app/helpers/sessions_helper.rb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module SessionsHelper
  def log_in(user)
    session[:user_id] = user.id
  end

  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  def logged_in?
    !current_user.nil?
  end

  def log_out
    # point1
    @current_user = nil
    session.delete(:user_id)
   # point2
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;app/controllers/sessions_controller.rb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class SessionsController &amp;lt; ApplicationController
  def destroy
    log_out
    redirect_to root_url
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;code&gt;application_controller.rb&lt;/code&gt; 和 &lt;code&gt;test_helper.rb&lt;/code&gt; 中都 include 了上面的 &lt;code&gt;SessionsHelper&lt;/code&gt;, 发生了一些奇怪的事情：&lt;/p&gt;

&lt;p&gt;集成测试中 &lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;delete logout_path
assert_not logged_in? # 这里出错, @current_user 取到了值
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 point1 和 point2 处打印&lt;code&gt;@current_user&lt;/code&gt; 却取不到。&lt;/p&gt;

&lt;p&gt;麻烦帮忙解释一下原因，谢谢&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Thu, 04 May 2017 15:09:21 +0800</pubDate>
      <link>https://ruby-china.org/topics/32930</link>
      <guid>https://ruby-china.org/topics/32930</guid>
    </item>
    <item>
      <title>编码问题</title>
      <description>&lt;p&gt;Q1:看起来完全不用考虑编码问题？&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt; s = ' 中  文'
=&amp;gt; " 中  文"
&amp;gt;&amp;gt; s[1]
=&amp;gt; "中"
&amp;gt;&amp;gt; s[3]
=&amp;gt; " "
&amp;gt;&amp;gt; s[4]
=&amp;gt; "文"
&amp;gt;&amp;gt; s.encoding
=&amp;gt; #&amp;lt;Encoding:UTF-8&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Q2:要输出'中'这个字符在 utf-8 下的二进制表示需要用哪个方法呢？&lt;/p&gt;

&lt;p&gt;谢谢。&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Wed, 13 Jul 2016 11:20:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/30512</link>
      <guid>https://ruby-china.org/topics/30512</guid>
    </item>
    <item>
      <title>关于 bootstrap-will_paginate 分页</title>
      <description>&lt;p&gt;用的&lt;code&gt;bootstrap-will_paginate&lt;/code&gt;来做的分页，
在第二页（page 为‘2’）删除一个用户，
操作之后如果还想重定向到第二页，有什么好办法来传递 page 参数吗？&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/71568ac58caf6e6c7b1aacc2ff6e9cd4.png" width="300px" alt=""&gt; &lt;img src="https://l.ruby-china.com/photo/2016/28e43a697ee85e2c3e45b04add2eee3f.png" width="300px" alt=""&gt;&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Tue, 05 Apr 2016 19:50:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/29550</link>
      <guid>https://ruby-china.org/topics/29550</guid>
    </item>
    <item>
      <title>关于自定义错误 message</title>
      <description>&lt;p&gt;目前的样子：
&lt;img src="https://l.ruby-china.com/photo/2016/fcbe7e163a552747b1a360a3cf4b17c3.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="用户模型验证的时候想要完全自定义错误信息"&gt;用户模型验证的时候想要完全自定义错误信息&lt;/h2&gt;
&lt;p&gt;Q1：attribute 的名字要怎么自定义为中文呢？
 Q2：如果把 :password_confirmation 的所有错误消息统一指定成『请确认密码』，要在哪里拦截呢？&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;user.rb&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class User &amp;lt; ActiveRecord::Base
  # 有效性验证
&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;## 用户名验证
  validates :name,
            presence: {message: "不得为空"},
            length: {maximum: 50,message: '昵称最多 50 个字符'}&lt;/p&gt;

&lt;p&gt;## Email 验证
  VALID_EMAIL_REGEX = /\A[\w+-.]+@[a-z\d-]+(.[a-z\d-]+)*.[a-z]+\z/i
  validates :email,
            presence: {message: "邮箱不能为空"},
            length: {maximum: 255},
            format: {with: VALID_EMAIL_REGEX, message: "请输入合法的邮箱地址"},
            uniqueness: {case_sensitive:false, message: "这个 Email 已经被占用了:("}  #仅仅为 ActiveRecord 的唯一性验证，不能保证 DB 的唯一性&lt;/p&gt;

&lt;p&gt;## 密码验证
   validates :password,
             length: {minimum: 6, message: "密码最少六位"}&lt;/p&gt;

&lt;p&gt;# 数据落地前的操作
  before_save{
    self.email = email.downcase
  }&lt;/p&gt;

&lt;p&gt;# 密码
  has_secure_password
end&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Tue, 29 Mar 2016 16:10:50 +0800</pubDate>
      <link>https://ruby-china.org/topics/29494</link>
      <guid>https://ruby-china.org/topics/29494</guid>
    </item>
    <item>
      <title>关于 私密笔记的安全</title>
      <description>&lt;p&gt;这是有道云笔记个人账户中的一篇笔记，点击『分享链接』产生的一个 link：
&lt;a href="http://note.youdao.com/share/?id=87af3b64fdf3643e87bc478dabed5d91&amp;amp;type=note" rel="nofollow" target="_blank"&gt;http://note.youdao.com/share/?id=87af3b64fdf3643e87bc478dabed5d91&amp;amp;type=note&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;然而这是一篇私人笔记，云笔记并没有『收回分享』这个功能。
（云笔记有阅读密码的功能，设置了密码的笔记 效果同上，可以无权限访问，不能收回分享）&lt;/p&gt;

&lt;p&gt;问题 1：从产品设计角度来说，这样是不是有问题？这里 share 的 id 可能是用什么算法生成的？暴力尝试 id 会不会扫描到用户的私密笔记？
问题 2：如果设计『收回分享』功能，怎样的实现比较好呢？&lt;/p&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Fri, 25 Mar 2016 15:29:10 +0800</pubDate>
      <link>https://ruby-china.org/topics/29460</link>
      <guid>https://ruby-china.org/topics/29460</guid>
    </item>
    <item>
      <title>在虚拟机上安装 Rails 环境, Nginx+Passenger</title>
      <description>&lt;h2 id="ubuntu14.04 安装 Rails 环境, Nginx Passenger"&gt;ubuntu14.04 安装 Rails 环境，Nginx Passenger&lt;/h2&gt;
&lt;p&gt;wiki 中也有介绍，但我还是遇到了一些问题。
步骤整理了一下，希望对像我一样的小白用户有帮助。&lt;/p&gt;
&lt;h3 id="新建部署用户"&gt;新建部署用户&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 创建新用户-dep
sudo useradd -m -s /bin/bash dep
sudo adduser dep sudo
sudo passwd

# 安装ssh远程连接
sudo apt-get install update
sudo apt-get install ssh

# 查看机器IP
ifconfig
# login as dep
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="安装ruby"&gt;安装 ruby&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo apt-get install curl
# 安装 RVM
\curl -sSL https://get.rvm.io | bash
# 激活 RVM
source .bashrc
# 产看RVM版本
rvm -v
# 用RVM安装Ruby
rvm install 2.3.0
# 查看RVM下所有ruby版本
rvm list
# 指定默认ruby
rvm alias create default 2.3.0
# 查看ruby命名位置
which ruby
# /home/dep/.rvm/rubies/ruby-2.3.0/bin/ruby
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="安装Nginx和Passenger"&gt;安装 Nginx 和 Passenger&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# APT安装 nginx+passenger
# 参考 https://www.phusionpassenger.com/library/install/nginx/install/oss/trusty/
# Install our PGP key and add HTTPS support for APT
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
sudo apt-get install -y apt-transport-https ca-certificates

# Add our APT repository
sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main &amp;gt; /etc/apt/sources.list.d/passenger.list'
sudo apt-get update

# Install Passenger + Nginx
sudo apt-get install -y nginx-extras passenger
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="安装依赖工具"&gt;安装依赖工具&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 安装nodejs，后面会有依赖
sudo apt-get install nodejs
# 安装Git
sudo apt-get install git
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="配置 Nginx"&gt;配置 Nginx&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vi /etc/nginx/nginx.conf
# 去掉下面两行的注释
# passenger_root /some-filename/locations.ini;
# passenger_ruby /usr/bin/passenger_free_ruby;

# 修改Nginx配置
sudo rm /etc/nginx/sites-enabled/default
sudo vi /etc/nginx/sites-enabled/example.com.conf

server {
    listen 80 default;
    server_name ror.cbd; # 如果是本地VM调试修改hosts文件
    root /home/deploy/code_from_git/toy_app/public;

    passenger_enabled on;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="部署代码"&gt;部署代码&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# clone 代码

# bundle安装gems
gem install bundle 
# 如果失败了就切回ruby-china的源
gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
gem sources -l

# 进入项目目录
bundle install
# 查看服务器的secret值
rake secret
# 在config/secrets.yml，替换掉production设置中的 &amp;lt;%= ENV["SECRET_KEY_BASE"] %&amp;gt;
# 代码 push &amp;amp;&amp;amp; pull

# 设置Rails运行环境 并 运行DB 迁移
RAILS_ENV=production rake db:create db:migrate
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="完成"&gt;完成&lt;/h3&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 重启 Nginx
sudo service nginx restart
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Tue, 22 Mar 2016 13:46:24 +0800</pubDate>
      <link>https://ruby-china.org/topics/29413</link>
      <guid>https://ruby-china.org/topics/29413</guid>
    </item>
    <item>
      <title>ruby-beautify 在 Atom 的编码问题</title>
      <description>&lt;pre class="highlight plaintext"&gt;&lt;code&gt;lib/ruby-beautify.rb:152:in indented_line': invalid byte sequence in US-ASCII (ArgumentError)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 Atom 中使用&lt;code&gt;Atom Beautify&lt;/code&gt;的插件，其中对 Ruby 的美化选用 ruby-beautify（ruby 用的 2.3.0）。
不是默认 utf-8 吗？为什么会 US-ASCII？&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;命令行中直接使用 ruby-beautify 没有问题。&lt;/li&gt;
&lt;li&gt;在 Gem 源码的正则后加‘u’还是报错。&lt;/li&gt;
&lt;li&gt;如果把目标文件的开头用 &lt;code&gt;# endcoding: utf-8&lt;/code&gt;标注，Atom 就不报错。&lt;/li&gt;
&lt;li&gt;换用 rubocop 不会报错了。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="那么问题出在哪呢？求前辈指点"&gt;那么问题出在哪呢？求前辈指点&lt;/h2&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Tue, 08 Mar 2016 16:21:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/29240</link>
      <guid>https://ruby-china.org/topics/29240</guid>
    </item>
    <item>
      <title>Render 模板时传值</title>
      <description>&lt;h2 id="模板主体"&gt;模板主体&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;app/views/articles/show.html.erb&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;标题:&amp;lt;/strong&amp;gt;
  &amp;lt;%= @article.title %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;内容:&amp;lt;/strong&amp;gt;
  &amp;lt;%= @article.text %&amp;gt;
&amp;lt;/p&amp;gt;
&amp;lt;br&amp;gt;

&amp;lt;h2&amp;gt;评论&amp;lt;/h2&amp;gt;
&amp;lt;%= render @article.comments %&amp;gt;
&amp;lt;br&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="插入的片段"&gt;插入的片段&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;app/views/comments/_comment.html.erb&lt;/code&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;p&amp;gt;
  &amp;lt;!--想在这里显示留言序号:1,2,3.. 不是comments的:id--&amp;gt;
  &amp;lt;strong&amp;gt;留言&amp;lt;%= ???  %&amp;gt;:&amp;lt;/strong&amp;gt;
  &amp;lt;%= comment.commenter %&amp;gt;
&amp;lt;/p&amp;gt;

&amp;lt;p&amp;gt;
  &amp;lt;strong&amp;gt;留言内容:&amp;lt;/strong&amp;gt;
  &amp;lt;%= comment.body %&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="疑问："&gt;疑问：&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;如上，想实现『留言 1』『留言 2』的效果，&lt;code&gt;&amp;lt;%= ???  %&amp;gt;&lt;/code&gt;里要填什么？&lt;/li&gt;
&lt;li&gt;多个模板片段拼接时，对象如何传递和处理？&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>wwwicbd</author>
      <pubDate>Thu, 03 Mar 2016 11:59:07 +0800</pubDate>
      <link>https://ruby-china.org/topics/29191</link>
      <guid>https://ruby-china.org/topics/29191</guid>
    </item>
  </channel>
</rss>
