<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>chunlea (Chunlea)</title>
    <link>https://ruby-china.org/chunlea</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>记一次 Ruby 内存泄漏的排查和修复</title>
      <description>&lt;p&gt;文章同步发到了公司的公众号「&lt;strong&gt;春丽说&lt;/strong&gt;」，欢迎关注。&lt;img title=":stuck_out_tongue_winking_eye:" alt="😜" src="https://twemoji.ruby-china.com/2/svg/1f61c.svg" class="twemoji"&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;自我检讨，文风太差了，评论里面有精简总结，节省时间必看。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;抱歉从发朋友圈到最终文章，拖了 n 个星期。因为这几个星期也在处理其他事情，同时也一直在找最终的泄漏根源，并且期望可以修复这个问题。当然我失败了。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;又一次捡起来以前的项目，既然要接手，那就准备一下升级到最新的 Rails 5.2.2 和 Ruby 新发的 2.6.1. 然而悲剧出现了，好不容易把依赖处理完了，CI 挂了，而且挂在了一个从来没有见到过的错误信息上：内存超出了 Circle CI 的限制。&lt;/p&gt;

&lt;p&gt;查询了 Circle CI 的相关文档 &lt;a href="https://circleci.com/docs/2.0/configuration-reference/#resource_class" rel="nofollow" target="_blank"&gt;https://circleci.com/docs/2.0/configuration-reference/#resource_class&lt;/a&gt; 发现，CircleCI 的内存限制 4GB。潜意识考虑的解决方案是增加内存。可是转眼一想，不对，因为可以确定在我离开这个项目的时候，项目本身是好的。所以我就默默的在我的电脑上跑一下看看，然后我吃惊了。😱&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2019/e1200a34-6c95-4f00-8a5f-fb2d9ceb8751.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;我首先把怀疑是升级 &lt;code&gt;Rails&lt;/code&gt; 导致的问题，于是开始逐步定位到底是哪几个测试如此吃内存。好在测试并不多，逐渐缩小范围查询到了这几个测试文件的某些行。&lt;/p&gt;

&lt;p&gt;跟朋友交流的过程中，突然想到了，莫非是 Ruby 2.6.1 的 bug？毕竟 Ruby 从 2.6.0 尝试引入了 JIT，保不齐在某个地方有特殊的触发条件，导致了 Ruby VM 的内存泄漏。要么我们的代码有问题，要么第三方的代码有问题，要么 Ruby 本身的实现有问题。想到这里，整个人精神了不少，开启了满满的 debug 之路。&lt;/p&gt;

&lt;p&gt;毕竟第一次见到活的而且可以稳定复现的内存泄漏问题，就跟路上捡到了百元大钞一样兴奋。（当然，我们要拾金不昧，捡到了钱要交给警察蜀黎，那么捡到了 bug 当然是要修复了！）&lt;/p&gt;

&lt;p&gt;经过简单的二分法查找，逐渐定位到了几个测试文件：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"zr_attendance/test/services/accounting_service_test.rb"&lt;/span&gt;

&lt;span class="s2"&gt;"zr_time_off/test/models/zr_time_off/request_test.rb:113#valid group days for regular hours"&lt;/span&gt;
&lt;span class="s2"&gt;"zr_time_off/test/models/zr_time_off/request_test.rb:130#valid group days for regular hours when cross weekend"&lt;/span&gt;
&lt;span class="s2"&gt;"zr_time_off/test/models/zr_time_off/request_test.rb:#"&lt;/span&gt;
&lt;span class="s2"&gt;"zr_time_off/test/models/zr_time_off/request_test.rb:#"&lt;/span&gt;
&lt;span class="s2"&gt;"zr_time_off/test/models/zr_time_off/request_test.rb:#"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我先把出现内存泄漏的测试用例都集中到某个文件中，然后拷贝一份当前的项目目录，把版本降到 2.5.3，然后跑一遍测试。2.5.3 版本完好，整个跑测试用例过程中，内存稳定在 300MB 以下。&lt;/p&gt;

&lt;p&gt;这个时候我们可以确定，内存泄漏问题出现在了 2.5.3 到 2.6.1 的某个版本中。这个时候，我在想，不知道这个版本是 2.5.3 到 2.6.0 还是 2.6.0 到 2.6.1 引入的。&lt;code&gt;rbenv install -l&lt;/code&gt; 给出的 ruby 列表，我们可以看到从 2.5.3 到 2.6.1 之间，经过了好几个版本。所以我们先确定一下是 2.6.0 就引入了还是 2.6.1 才引入，以及是否在最新的 2.7.0-dev 里面就已经解决。于是我可能需要安装四个版本的 ruby。（这纯粹是闲的）&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2019/4b8eac01-d34e-447a-a4de-d1f595bf944a.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;经过几个版本，我发现 ruby 2.7.0-dev 仍然有泄漏问题，瞬间开心了很多，至少证明了这是一个必现的问题，而且是 ruby 2.6.0 引入的。那么理论上，我只要能定位到 在 ruby 2.5.3 版本工作正常的代码在新代码上会出现内存泄漏，那么通过比较两个 ruby 代码版本实现的差异，就能定位到泄漏点。我有种感觉，这个泄漏点应该是来自 ruby 本身。摩拳擦掌准备深挖这个 bug！&lt;/p&gt;

&lt;p&gt;通过测试用例，用二分法注释掉代码的笨方法，我逐渐定位到几个测试用例出错的代码行，并根据这个代码行，找到最终在实现里面出现问题的地方。当然对于用惯了 &lt;code&gt;print&lt;/code&gt; 大法的人来说，其实就是个体力活。&lt;/p&gt;

&lt;p&gt;经过一段苦找，测试用例导致内存泄漏的代码被我精确到了两个点。但是因为这个项目在 2.5.3 上面跑的非常好，而且其实已经经过几个月的线上运行，我们可以认为这个项目在我们找到的对应业务逻辑实现的代码中是没有错误的。而且测试几个 ruby 版本的时候，我们精确的控制了变量，Rails 版本和其他第三方 Gems 版本都一致。&lt;/p&gt;

&lt;p&gt;于是我把代码找到，去 console 里面执行，看看 console 里面是否会同样出现内存泄漏问题。很幸运，在找到的两个测试用例调用的代码里面，我在第二个代码里面复现了内存泄漏。&lt;/p&gt;

&lt;p&gt;于是，根据代码，我们先从第二个点入手。第二个代码是创建一个请假记录的数据库记录，是一个标准的 Rails 实现，在执行过程中，我发现到这一条 SQL 时候，内存就开始暴涨，所以基本可以确定是这个问题。而另一个代码没有在 console 里面复现，却在跑测试用例的时候出现内存泄漏。考虑了一下，应该是 development 环境对应的数据里面没有跟 worktime 相关的内容，导致无法触发下面的 SQL。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2019/65824fa5-ea59-4696-bd95-305b7ebec33f.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;因为两个 Ruby 版本，早前的 2.5.3 是正常的，所以可以排除数据库的问题，而且我们服务器用的是 PostgreSQL，出了 bug 也不一定会被我遇到。另外之所以发现这个问题，是因为 CircleCI 跑测试的时候，超出了 CI 限定的最大内存，所以可以证明这个问题在 Linux 和我自用的 macOS 上都有相同的问题。&lt;/p&gt;

&lt;p&gt;一个简单的复现代码如下：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;identity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ZrCore&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Identity&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="no"&gt;ZrTimeOff&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create!&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="ss"&gt;identity: &lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;category: :in_lieu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;start_time: &lt;/span&gt;&lt;span class="s1"&gt;'2017-12-1 9:00'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;in_time_zone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Beijing'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;end_time: &lt;/span&gt;&lt;span class="s1"&gt;'2017-12-1 18:00'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;in_time_zone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Beijing'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;created_source: &lt;/span&gt;&lt;span class="n"&gt;identity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;status: :passed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;unit: :halfhour&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;precision: :raw&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;继续深究 &lt;code&gt;ZrTimeOff::Request&lt;/code&gt; 的实现，发现只要注释掉这行代码，就不会有内存泄漏。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;calculate_unit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;by_day?&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'day'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'hour'&lt;/span&gt;
&lt;span class="c1"&gt;# send("calc_group_days_by_#{calculate_unit}")&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;看样子，我们离罪魁祸首越来越近了，所以我准备使用 &lt;code&gt;binding.pry&lt;/code&gt; 在这个地方打断点。从现在看，摆在我们前面的有两条路，一条是 &lt;code&gt;ruby&lt;/code&gt; 的 &lt;code&gt;send&lt;/code&gt; 方法实现改过，导致行为跟原来的不一致（后来证明想多了），另外一个就是我们通过 &lt;code&gt;send&lt;/code&gt; 调用的两个动态方法 &lt;code&gt;calc_group_days_by_day&lt;/code&gt; 和 &lt;code&gt;calc_group_days_by_hour&lt;/code&gt; 的实现有问题。&lt;/p&gt;

&lt;p&gt;通过打断点，我现在不确定 &lt;code&gt;send&lt;/code&gt; 方法的实现是否有问题，但是显然，当我调用 &lt;code&gt;calc_group_days_by_hour&lt;/code&gt; 的时候，出现了内存泄漏。继续深挖 &lt;code&gt;calc_group_days_by_hour&lt;/code&gt; 的实现。&lt;/p&gt;

&lt;p&gt;具体细节因为涉及一些业务场景，略过一部分，通过深挖，定位到一个名为 &lt;code&gt;ZrAttendance::DailyQuery&lt;/code&gt; 类的一个 &lt;code&gt;overlap_minutes&lt;/code&gt; 方法。&lt;/p&gt;

&lt;p&gt;发现，只要涉及执行 &lt;code&gt;to_minutes_array&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;Range&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_minutes_array&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;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&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;last&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;step&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="nf"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;单纯从代码看，没有任何问题。现在似乎可以确定问题了，这个实现在 ruby 2.5.3 和 2.6.0 上表现不一致。&lt;/p&gt;

&lt;p&gt;不过，这只是锁定了，冰山上面的部分，至于冰山下面的部分，到底为什么不一致，仍然有很多地方需要深挖。&lt;/p&gt;

&lt;p&gt;于是，我们就可以把问题抽象成 &lt;code&gt;(1512090000.. 1512122340).step(1.minute).to_a.count&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;然而经过简单的分析，Range 的长度是 32340，加上 Step 之后仅仅 540 个元素，把 540 个元素转换成数组，无论如何也不至于出现内存泄漏。而按照内存最高占到数 G 大小的情况来分析，显然某个地方出现了严重的问题。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'active_support/all'&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如此简单的代码在 2.6.1 就爆掉了，我们有理由相信 Ruby 的实现出现了些许问题。&lt;/p&gt;

&lt;p&gt;然而在找 bug 的过程中，某天跟朋友在酒吧里面掏出电脑就是一顿讨论，在讨论的过程中，我们发现其实在一个月以前已经有人给 Rails 项目提出了 Issue &lt;a href="https://github.com/rails/rails/issues/34888" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/issues/34888&lt;/a&gt; ，并且 &lt;a href="/tenderlove" class="user-mention" title="@tenderlove"&gt;&lt;i&gt;@&lt;/i&gt;tenderlove&lt;/a&gt; &lt;a href="https://github.com/rails/rails/pull/34899" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/pull/34899&lt;/a&gt; 给出了简单的修复，但是 &lt;a href="/tenderlove" class="user-mention" title="@tenderlove"&gt;&lt;i&gt;@&lt;/i&gt;tenderlove&lt;/a&gt; 同时强调，虽然修复了，但是性能在 2.5 和 2.6 比较，2.6 慢了很多。&lt;/p&gt;

&lt;p&gt;那么，不影响我们继续深挖原因。通过测试，我们发现，&lt;/p&gt;

&lt;p&gt;在 2.5.3 上，&lt;code&gt;(1..200).step(8.seconds).class #=&amp;gt; Enumerator&lt;/code&gt;, &lt;/p&gt;

&lt;p&gt;而在 2.6.1 版本上 &lt;code&gt;(1..200).step(8.seconds).class #=&amp;gt; Enumerator::ArithmeticSequence&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;而 &lt;code&gt;Enumerator::ArithmeticSequence&lt;/code&gt; 这个是 2.6.0 新加的类，所以问题应该是处在这里了。那么我们该如何界定具体问题出现在哪里呢？我想到之前参加 RubyKaigi 的时候， &lt;a href="https://speakerdeck.com/watson/how-to-optimize-ruby-internal" rel="nofollow" target="_blank"&gt;https://speakerdeck.com/watson/how-to-optimize-ruby-internal&lt;/a&gt; 给出了一种可以通过 Instruments 来调试找出性能问题的方法。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2019/80fcbbb0-8d51-4ae3-9bd3-5bd972b9b552.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;通过 Call Trees，我们可以看到，绝大多数内存都出现在了 &lt;code&gt;arith_seq_each&lt;/code&gt; 调用的 &lt;code&gt;rb_int_plus&lt;/code&gt; 里面，那么我们可以断定，这个地方有什么问题导致内存出现暴涨，切一定程度下形成了内存泄漏。经过 &lt;code&gt;printf&lt;/code&gt; 大法，我最终发现问题在于 &lt;code&gt;rb_int_plus&lt;/code&gt; 里面的 &lt;code&gt;rb_num_coerce_bin(x, y, '+');&lt;/code&gt;。这个方法最终会落地到：
&lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/duration.rb#L47" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/blob/master/activesupport/lib/active_support/duration.rb#L47&lt;/a&gt;\&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Duration&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;new_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_parts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;显然，随着 &lt;code&gt;arith_seq_each&lt;/code&gt; 的调用，这里逐渐在执行 &lt;code&gt;ActiveSupport::Duration#new&lt;/code&gt;，我发现了一个奇怪的现象，而这个现象极有可能是导致最终内存崩溃的原因：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2019/fd5972a4-d362-4624-9d7c-a4f8c959c47c.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;我们可以看到，这里随着 &lt;code&gt;arith_seq_each&lt;/code&gt; 我们发现 &lt;code&gt;ActiveSupport::Duration#+&lt;/code&gt; 的次数会成指数型增长，而随着指数增长的结果就是内存爆掉。为啥 &lt;code&gt;Enumerator&lt;/code&gt; 不会崩掉，因为根本就不会跑到这里嘛！而这里的问题也确实如 &lt;a href="https://github.com/rails/rails/pull/34899" rel="nofollow" target="_blank"&gt;https://github.com/rails/rails/pull/34899&lt;/a&gt; 给出的修复，而性能的问题也是出现在：&lt;code&gt;rb_num_coerce_bin(x, y, '+');&lt;/code&gt; 最后落地的实现上。&lt;/p&gt;

&lt;p&gt;本来还想研究一下，然后从源头修复掉，后来发现最简单的方案就是：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(1..200).step(8.minute) #=&amp;gt;
(1..200).step(8.minute.to_i)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;完美！&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;其实这篇烂尾了，但是思前想后，还是决定发出来，有些有趣的信息说不定可以给大家一些参考。&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <author>chunlea</author>
      <pubDate>Sun, 31 Mar 2019 01:52:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/38328</link>
      <guid>https://ruby-china.org/topics/38328</guid>
    </item>
    <item>
      <title>MobaXterm, 从此基于 Windows 10 开发 Rails</title>
      <description>&lt;p&gt;Windows 10 在某个 Insider 版本之后，提供了 Bash on Ubuntu on Windows 这个逆天的功能，无奈微软自带的 cmd 终究不成气候，即使支持了 vt100，包括特殊字符、颜色配置等众多功能都不支持。今天偶然发现 &lt;a href="http://mobaxterm.mobatek.net/" rel="nofollow" target="_blank"&gt;http://mobaxterm.mobatek.net/&lt;/a&gt; 支持 Bash on Ubuntu on Windows，完美解决了 Windows 下没有可用 terminal 的问题。&lt;/p&gt;

&lt;p&gt;加之前面的版本，微软修复了对 ZSH 的支持问题，所以现在的结果就是！完美！&lt;/p&gt;

&lt;p&gt;稍后补图。&lt;/p&gt;

&lt;p&gt;反正之后的开发，就是 Docker on Windows，基于 Hyper-V，然后再加 Bash on Ubuntu on Windows，随便折腾！&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Mon, 04 Jul 2016 00:39:04 +0800</pubDate>
      <link>https://ruby-china.org/topics/30438</link>
      <guid>https://ruby-china.org/topics/30438</guid>
    </item>
    <item>
      <title>Stripe 推出 Atlas，想要使用 Stripe 来作为支付渠道的可以尝试</title>
      <description>&lt;p&gt;&lt;a href="https://stripe.com/atlas" rel="nofollow" target="_blank"&gt;https://stripe.com/atlas&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;支付宝简直就是……这个无需多说。Stripe 应该是公认的对开发者最友好的支付渠道，可是使用 Stripe 需要美国 SSN 和 Bank Account，解决方法就是肉身到美国的时候顺手注册一个银行帐号或者去美国开公司。创业公司去美国开公司应该是一个很有价值的事情，你可以去美国开一家分公司，然后给自己 L1 签证…… 这个事情理论上是可以的，但是我不是律师，所以移民的问题，还是找律师好了。&lt;/p&gt;

&lt;p&gt;美国开公司的成本是很低的，主要是解决税务问题，而很多州的规定是只要不再本州经营，不会收税。然后至于，Stripe 收了美国人的钱算不算在美国经营，这个我也在查资料。&lt;/p&gt;

&lt;p&gt;Atlas 就是 Stripe 和会计税务所合作帮助身在海外的人注册美国公司，拿下美国公司银行帐号、税号，并且提供税务咨询。价格是 500 美金，这个真的很良心。&lt;/p&gt;

&lt;p&gt;另外，Stripe 现在支持支付宝了，那么如果能用，干嘛不用。&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Sat, 27 Feb 2016 07:43:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/29123</link>
      <guid>https://ruby-china.org/topics/29123</guid>
    </item>
    <item>
      <title>What your desks look like?</title>
      <description>&lt;p&gt;看到 &lt;a href="/Rei" class="user-mention" title="@Rei"&gt;&lt;i&gt;@&lt;/i&gt;Rei&lt;/a&gt; 的帖子 &lt;a href="https://ruby-china.org/topics/23747" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/23747&lt;/a&gt;，的确程序员对于工作环境有时候会有偏执。我们强调的是享受编程对不？&lt;/p&gt;
&lt;h2 id="所以大家都来晒自己的办公环境吧"&gt;所以大家都来晒自己的办公环境吧&lt;/h2&gt;&lt;h2 id="我先来我的："&gt;我先来我的：&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/6d61664719cad8487ba28a0e6fdc8984.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;现在宿舍的环境，不过马上就要滚蛋了。duetdisplay 的出现终于让 iPad 不再是摆设，可以放个终端什么的完全没有压力。强烈推荐。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="某次在南京尝试的站立办公桌，我想说如果穿鞋的话，还是不要站立办公的好。"&gt;某次在南京尝试的站立办公桌，我想说如果穿鞋的话，还是不要站立办公的好。&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/775a97e97361dfad10e25092ed6664e6.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/56350cce66dbd39da7ca088c7c41083e.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;值得推荐的：
Macbook Pro
DuetDisplay + iPad
HHKB
RainDesign Macbook 支架&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="来来来，大家快来晒起来。什么椅子啦，桌子了统统亮亮，顺便推荐下你认为最好最值得推荐的码代码利器。"&gt;来来来，大家快来晒起来。什么椅子啦，桌子了统统亮亮，顺便推荐下你认为最好最值得推荐的码代码利器。&lt;/h2&gt;</description>
      <author>chunlea</author>
      <pubDate>Thu, 15 Jan 2015 11:46:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/23754</link>
      <guid>https://ruby-china.org/topics/23754</guid>
    </item>
    <item>
      <title>Chef 非常好的学习资料。 http://chef.leopard.in.ua</title>
      <description>&lt;p&gt;比较不错的 Chef 的学习资料，简单易懂。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://chef.leopard.in.ua" rel="nofollow" target="_blank"&gt;http://chef.leopard.in.ua&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;提供免费的 PDF，ePub 等格式下载。&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Mon, 15 Dec 2014 11:00:58 +0800</pubDate>
      <link>https://ruby-china.org/topics/23199</link>
      <guid>https://ruby-china.org/topics/23199</guid>
    </item>
    <item>
      <title>［文章分享］https://codelation.com/blog/rails-restful-api-just-add-water</title>
      <description>&lt;p&gt;&lt;a href="https://codelation.com/blog/rails-restful-api-just-add-water" rel="nofollow" target="_blank"&gt;https://codelation.com/blog/rails-restful-api-just-add-water&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;介绍懒得写了，大家自己看吧。&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Sun, 07 Dec 2014 12:38:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/23066</link>
      <guid>https://ruby-china.org/topics/23066</guid>
    </item>
    <item>
      <title>RubyMotion Workshop Beijing 资料总结</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2014/7256120e1e04d49da28ad64371dbe967.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;很高兴，第一次负责的 RubyMotion Workshop 终于结束了。结果还算圆满，希望参加的童鞋可以吐吐槽，让我们成长的更快。&lt;/p&gt;

&lt;p&gt;介于有如此多的同学对 RubyMotion 感兴趣，那么我汇总下此次的 Workshop 的相关资料，顺带补充相关资料。&lt;/p&gt;

&lt;p&gt;此次 RubyMotion Workshop 的 Slide 和资料做的比较仓促，可能参考意义并不是想象中的大。但是我还是决定放出尽可能的多的资料供大家学习。&lt;/p&gt;

&lt;p&gt;链接：&lt;a href="http://pan.baidu.com/s/1qWqelxq" rel="nofollow" target="_blank"&gt;http://pan.baidu.com/s/1qWqelxq&lt;/a&gt; 密码：p5q9  包括 Keynote 和会上发放的 PDF 介绍文档。&lt;/p&gt;

&lt;p&gt;限于官方的要求，我不能大规模分享最新版本的评测版。需要的同学请发送邮件到 ichunlea##me.com，我会给大家回复相关的包。（可能稍微慢点）&lt;/p&gt;

&lt;p&gt;部分优质资料总结：
链接：&lt;a href="http://pan.baidu.com/s/1hq7p080" rel="nofollow" target="_blank"&gt;http://pan.baidu.com/s/1hq7p080&lt;/a&gt; 密码：3d61  #Inspect 2014 所有视频，rubymotion 的第一届会议
链接：&lt;a href="http://pan.baidu.com/s/1c0GRbhQ" rel="nofollow" target="_blank"&gt;http://pan.baidu.com/s/1c0GRbhQ&lt;/a&gt; 密码：t4qa 官方提供的 Dash.app 的相关内容，后期由于版权问题，就找不到了。这个可以用。
其他资料，参考 PDF 中提供的链接&lt;/p&gt;

&lt;p&gt;我们希望可以总结这次的经验，争取在国内推广 RubyMotion。&lt;/p&gt;

&lt;p&gt;最后，谢谢大家的支持。&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Sun, 02 Nov 2014 23:17:51 +0800</pubDate>
      <link>https://ruby-china.org/topics/22416</link>
      <guid>https://ruby-china.org/topics/22416</guid>
    </item>
    <item>
      <title>RubyMotion Workshop 之 iOS 开发实战</title>
      <description>&lt;h2 id="P.S.  Workshop已经结束，已经更新部分资料： https://ruby-china.org/topics/22416"&gt;P.S.  Workshop 已经结束，已经更新部分资料： &lt;a href="https://ruby-china.org/topics/22416" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/22416&lt;/a&gt;
&lt;/h2&gt;
&lt;hr&gt;

&lt;p&gt;熟悉 Ruby 的你是否期待可以用你最爱的 Ruby 语言开发手机端 App？精通 Rails 的你是否期待有一天可以亲自动手为自己的项目增加 iOS 和 Android 的客户端？现在，这些都不再仅仅是期待，因为我们有了优雅的解决方案—— RubyMotion。&lt;/p&gt;

&lt;p&gt;你不需要额外学习另一种编程语言，只需要用你所热爱的 Ruby，就可以横跨 iOS，OSX 和 Android 三大平台，成为名副其实的 Full Stack Ruby Jedi。&lt;/p&gt;

&lt;p&gt;此次 Workshop，我们会使用最新版的 RubyMotion，并通过一个小项目，让参与者体会 RubyMotion 开发的完整流程，熟悉 RubyMotion 开发 iOS 应用的模式。并介绍 RubyMotion 社区是如何通过 ProMotion 和 RubyMotionQuery 等 Gem 来简化移动开发，使得移动开发变的越来越优雅。&lt;/p&gt;

&lt;p&gt;未来创业团队最佳配置就是美工和 Ruby 程序员。未来的 Ruby 程序员，通过 RubyMotion 和 Rails 的助力，便可以轻松横跨四大平台（Web、OS X、iOS、Andoroid），让你的创意以最快的速度落地。&lt;/p&gt;

&lt;p&gt;而这一切的一切，都是源自 Ruby 优良的基因。&lt;/p&gt;
&lt;h2 id="活动时间："&gt;活动时间：&lt;/h2&gt;
&lt;p&gt;2014 年 11 月 2 日（周日）上午 9:00&lt;/p&gt;
&lt;h2 id="活动地点："&gt;活动地点：&lt;/h2&gt;
&lt;p&gt;北京中关村创业街 3W 咖啡&lt;/p&gt;
&lt;h2 id="报名须知："&gt;报名须知：&lt;/h2&gt;
&lt;p&gt;活动人数 30 人，需要提前报名并提供姓名，邮箱等信息，活动前会与报名者电话联系并确认信息。
报名者需有 Ruby 语言基础，若有 Rails 或 Objective-C 开发经验，甚好。
需要自带 Mac 电脑（也可以结对使用），需要 &lt;strong&gt;提前安装 XCode&lt;/strong&gt;，我们建议最新版。
我们会在 11 月 1 号之前，邮件联系所有参加者，提前分发测试版安装包和环境搭建指南。
有任何疑问，可以联系 Wechat：XXXXXXXXXX(已经结束)&lt;/p&gt;
&lt;h2 id="活动需要提前报名，请戳： https://jinshuju.net/f/vUDytY"&gt;活动需要提前报名，请戳： &lt;a href="https://jinshuju.net/f/vUDytY" rel="nofollow" target="_blank"&gt;https://jinshuju.net/f/vUDytY&lt;/a&gt;
&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;感谢 &lt;a href="/yedingding" class="user-mention" title="@yedingding"&gt;&lt;i&gt;@&lt;/i&gt;yedingding&lt;/a&gt; 和 &lt;a href="/jasl" class="user-mention" title="@jasl"&gt;&lt;i&gt;@&lt;/i&gt;jasl&lt;/a&gt; 的信任，可以让我来负责这次 Workshop，也感谢 &lt;a href="/smartweb" class="user-mention" title="@smartweb"&gt;&lt;i&gt;@&lt;/i&gt;smartweb&lt;/a&gt; 和 &lt;a href="/lifedim" class="user-mention" title="@lifedim"&gt;&lt;i&gt;@&lt;/i&gt;lifedim&lt;/a&gt; 给予我的无私的支持和鼓励。我们一定尽所能让对 RubyMotion 感兴趣的你满意而归。&lt;/p&gt;

&lt;p&gt;同时，我们也欢迎熟悉 RubyMotion 开发的你来我们这儿，分享你使用 RubyMotion 的经验。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr&gt;
&lt;h2 id="剧透模式："&gt; 剧透模式：&lt;/h2&gt;
&lt;p&gt;目前暂定的大家动手写一个自己的软件，到时我们会提供一个完整的项目文档，供大家参考。虽然 RubyMotion 不能像 RailsGirls 那样请到很多的导师助阵，但是我们一定通过设计精良的教程和活动流程，让大家低门槛的不如 RubyMotion 的世界。
如果 workshop 时间允许，我们还可以请 &lt;a href="/smartweb" class="user-mention" title="@smartweb"&gt;&lt;i&gt;@&lt;/i&gt;smartweb&lt;/a&gt; 讲讲他们用 RubyMotion 的经验，&lt;a href="/lifedim" class="user-mention" title="@lifedim"&gt;&lt;i&gt;@&lt;/i&gt;lifedim&lt;/a&gt; 分析分析 Swift 和 RubyMotion 的优劣（我知道你们一定感兴趣，我去补 Swift 的知识了）。&lt;/p&gt;

&lt;p&gt;另，我们会给这次参加 RubyConfChina 2014 的人提供一个关于 RubyMotion 的惊喜哦 ^_^&lt;/p&gt;

&lt;hr&gt;

&lt;blockquote&gt;
&lt;p&gt;第一次负责这个事情，想想真有点小激动呢。欢迎到时大家极力吐槽，促进我们快快成长，喵～&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <author>chunlea</author>
      <pubDate>Thu, 23 Oct 2014 21:38:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/22228</link>
      <guid>https://ruby-china.org/topics/22228</guid>
    </item>
    <item>
      <title>在 rbenv 环境下使用 Whenever 的小技巧</title>
      <description>&lt;p&gt;项目需要进行数据库备份，参照
&lt;a href="https://ruby-china.org/topics/4710" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/4710&lt;/a&gt;
&lt;a href="https://ruby-china.org/topics/1976" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/1976&lt;/a&gt;
选择了 Backup 这个 Gem，幸福度瞬间提升。&lt;/p&gt;

&lt;p&gt;但是，由于 VPS 上面使用 rbenv 管理 ruby 版本，whenever 生成的 corntab 命令始终无法正确执行，但是在 shell 下确可以正确执行。初步判断是由于 rbenv 产生的问题。&lt;/p&gt;

&lt;p&gt;最终找到了这个方法，优雅的解决了问题：&lt;a href="http://stackoverflow.com/a/21060911" rel="nofollow" target="_blank"&gt;http://stackoverflow.com/a/21060911&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;解决方法就是在 &lt;code&gt;config/schedule.rb&lt;/code&gt; 的顶端，加入如下命令：
&lt;code&gt;env :PATH, ENV['PATH']&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;经测试，问题解决，whenever 生成的 corntab 可以正确执行。&lt;/p&gt;

&lt;p&gt;希望可以给遇到相同问题的人一点帮助。&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Wed, 24 Sep 2014 09:02:54 +0800</pubDate>
      <link>https://ruby-china.org/topics/21693</link>
      <guid>https://ruby-china.org/topics/21693</guid>
    </item>
    <item>
      <title>Rails 的两个 Tips，ENV 变量和 CarrierWave 文件路径</title>
      <description>&lt;p&gt;需要将应用程序从 Heroku 转到 DigitalOcean 上，遇到两个问题，问题描述和解决方案如下：&lt;/p&gt;
&lt;h2 id="问题一：ENV 环境变量。"&gt;问题一：ENV 环境变量。&lt;/h2&gt;
&lt;p&gt;Heroku 有非常好的管理 ENV 变量的机制，但是对于 VPS 一直未见特别完美的方案。有很多的 Gem 可以用，我也用过 SettingsLogics，但是显然，受制于加载顺序，SettingsLogic 对于 database.yml 或者 initializers 一类的文件基本就没用了。今天发现下面的这个方法，感觉符合自己的预期，故推荐下。
参考：&lt;a href="http://quickleft.com/blog/simple-rails-app-configuration-settings" rel="nofollow" target="_blank"&gt;http://quickleft.com/blog/simple-rails-app-configuration-settings&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;主要两点：
在  &lt;code&gt;config/application.rb&lt;/code&gt; 文件的 &lt;code&gt;module Whatever&lt;/code&gt; 之前，加入：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt; &lt;span class="no"&gt;YAML&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'config/application.yml'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;rescue&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后创建  &lt;code&gt;config/application.yml&lt;/code&gt;, 内容如下：&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;defaults&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev@example.com&lt;/span&gt;
  &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foo123&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*defaults&lt;/span&gt;

&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*defaults&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test@example.com&lt;/span&gt;

&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*defaults&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;info@example.com&lt;/span&gt;
  &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;321oof&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之后你就可以使用类似 &lt;code&gt;ENV['email']&lt;/code&gt; 的变量了。不过这个也有一个非常小的问题，就是 YAML 文件只能一层，不能进行嵌套，也不支持 YAML 的数组或者列表的结构。&lt;/p&gt;

&lt;p&gt;不要将 &lt;code&gt;config/application.yml&lt;/code&gt; 签到你的代码库中，由于 &lt;code&gt;rescue {}&lt;/code&gt; 的存在，因此，即使没有 &lt;code&gt;config/application.yml&lt;/code&gt; 这个文件，也不会挂掉。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="问题二：CarrierWave 环境和路径问题"&gt;问题二：CarrierWave 环境和路径问题&lt;/h2&gt;
&lt;p&gt;项目开发环境用 file 存储，生产环境通过 fog 来用 s3 这个也没有问题，唯独用的时候才发现 file 默认的是相对路径。可是我这个是给移动端用的，你给我想对路径我还怎么搞…… 后来发现，可以简单的设置 CarrierWave.configure.asset_host 来给开发环境设置默认使用绝对路径。直接贴配置文件吧，相信大家明白什么意思。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# File at config/initializers/carrierwave.rb&lt;/span&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'carrierwave'&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'carrierwave/orm/activerecord'&lt;/span&gt;

&lt;span class="no"&gt;CarrierWave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&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;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;development?&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test?&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;storage&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:file&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asset_host&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'asset_host'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# 这行的作用就是强制在file的url前面附加 ENV['asset_host'] 的内容&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:fog&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fog_credentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="ss"&gt;:provider&lt;/span&gt;                            &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'AWS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                        &lt;span class="c1"&gt;# required&lt;/span&gt;
      &lt;span class="ss"&gt;:aws_access_key_id&lt;/span&gt;         &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'aws_access_key_id'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;        &lt;span class="c1"&gt;# your aws access key id&lt;/span&gt;
      &lt;span class="ss"&gt;:aws_secret_access_key&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;ENV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'aws_secret_access_key'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# your aws secret access key&lt;/span&gt;
      &lt;span class="c1"&gt;# :region                            =&amp;gt; ENV['S3_REGION']                    # your bucket's region in S3, defaults to 'us-east-1'&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;# your S3 bucket name&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fog_directory&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'*********'&lt;/span&gt;
    &lt;span class="c1"&gt;# custome your domain on aws S3, defaults to nil&lt;/span&gt;
    &lt;span class="c1"&gt;# config.fog_host       = 'http://myapp.com'&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fog_public&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt;                                     &lt;span class="c1"&gt;# optional, defaults to true&lt;/span&gt;
    &lt;span class="c1"&gt;# config.fog_attributes = {'Cache-Control'=&amp;gt;'max-age=315576000'}  # optional, defaults to {}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>chunlea</author>
      <pubDate>Mon, 08 Sep 2014 03:43:31 +0800</pubDate>
      <link>https://ruby-china.org/topics/21420</link>
      <guid>https://ruby-china.org/topics/21420</guid>
    </item>
    <item>
      <title>RubyMotion 的 Android 支持似乎马上就要发布了</title>
      <description>&lt;p&gt;偶尔上 Twitter，看到这条 Tweet，似乎 RubyMotion 的 Android 支持马上就要发布了，当然，应该是 Beta 版本的。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Really need a break. Off to Malta for a 7-day no-phone no-internet vacation (my first in 3 years). Android beta will come right after. :-)
From &lt;a href="/lrz" class="user-mention" title="@lrz"&gt;&lt;i&gt;@&lt;/i&gt;lrz&lt;/a&gt; (Laurent Sansonetti)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr&gt;

&lt;p&gt;另外一个好消息是 Github Pages 也升级到 Jekyll 2.0 了，原生支持 CoffeeScript 和 Sass，改进好大啊……&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Thu, 31 Jul 2014 11:44:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/20774</link>
      <guid>https://ruby-china.org/topics/20774</guid>
    </item>
    <item>
      <title>关于导航了最右元素在 Yosemite 下偏离的 Bug</title>
      <description>&lt;p&gt;这个问题好像有人提过，今天准备将环境彻底换到 Yosemite，有发现了这个 Bug。随手尝试了下，可能是 Yosemite 里面自带的 Safari 关于元素的计算导致的，上两张图：&lt;/p&gt;
&lt;h2 id="Bug 重现"&gt;Bug 重现&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2014/2220b21b9997a29db6d05fc719f1a2ec.png" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="发现的可能的解决方法"&gt;发现的可能的解决方法&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2014/b3d6eaaebdef3d56f2a66f98fac63095.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;注意红色框中的代码的区别。
&lt;a href="/huacnlee" class="user-mention" title="@huacnlee"&gt;&lt;i&gt;@&lt;/i&gt;huacnlee&lt;/a&gt; &lt;a href="/rei" class="user-mention" title="@rei"&gt;&lt;i&gt;@&lt;/i&gt;rei&lt;/a&gt; &lt;a href="/lgn21st" class="user-mention" title="@lgn21st"&gt;&lt;i&gt;@&lt;/i&gt;lgn21st&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;同时求解具体原因，感觉这个 Bug 很有意思。&lt;/p&gt;

&lt;p&gt;补充：
似乎是将 ul 元素放到 form 元素里面，而 form 元素有一个 margin-top:6px 的属性被 ul 元素给继承了？&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Mon, 21 Jul 2014 20:52:01 +0800</pubDate>
      <link>https://ruby-china.org/topics/20613</link>
      <guid>https://ruby-china.org/topics/20613</guid>
    </item>
    <item>
      <title>RubyMotion Conference: #inspect 2014 的视频录像释出 [附百度云下载链接]</title>
      <description>&lt;p&gt;视频地址如下：
&lt;a href="http://confreaks.com/events/inspect" rel="nofollow" target="_blank"&gt;http://confreaks.com/events/inspect&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;最近在准备考试，所以没有时间。如果以后有空，会帮忙转到国内的网盘。 &lt;del&gt;如果有各位可以帮忙，更好。&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;目前最后一个视频（UnderOS, Native IOS For Web-Developers）有点问题，暂且不处理了……没时间&lt;/p&gt;

&lt;p&gt;链接：&lt;a href="http://pan.baidu.com/s/1c0oxDNq" rel="nofollow" target="_blank"&gt;http://pan.baidu.com/s/1c0oxDNq&lt;/a&gt; 提取密码:jun0&lt;/p&gt;

&lt;p&gt;仅仅看了第一个视频，总结如下：
RubyMotion 3.0 的三个主要 Features:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;性能提升&lt;/li&gt;
&lt;li&gt;开发流程得以优化，可以动态加载代码（类似 Rails 不用重复重启服务器，终于可以不用写一行代码也重新编译了，赞）&lt;/li&gt;
&lt;li&gt;支持 Android&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>chunlea</author>
      <pubDate>Sat, 21 Jun 2014 13:36:43 +0800</pubDate>
      <link>https://ruby-china.org/topics/20095</link>
      <guid>https://ruby-china.org/topics/20095</guid>
    </item>
    <item>
      <title>Laurent Sansonetti 关于 RubyMotion 开发 Android 的视频</title>
      <description>&lt;p&gt;原始链接：&lt;a href="http://brug.be/gatherings/brug-june-2014" rel="nofollow" target="_blank"&gt;http://brug.be/gatherings/brug-june-2014&lt;/a&gt;
Youtube：&lt;a href="https://www.youtube.com/watch?v=fOYtEzFPrEM&amp;amp;list=PLzT3e3NJg9r4l0xl1saTSz3kBEK0W7flR&amp;amp;index=5" rel="nofollow" target="_blank"&gt;https://www.youtube.com/watch?v=fOYtEzFPrEM&amp;amp;list=PLzT3e3NJg9r4l0xl1saTSz3kBEK0W7flR&amp;amp;index=5&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;百度网盘链接：
链接：&lt;a href="http://pan.baidu.com/s/1gd02Lvd" rel="nofollow" target="_blank"&gt;http://pan.baidu.com/s/1gd02Lvd&lt;/a&gt; 密码：83bp&lt;/p&gt;

&lt;p&gt;是不是该设置一个 RubyMotion 的节点？&lt;a href="/huacnlee" class="user-mention" title="@huacnlee"&gt;&lt;i&gt;@&lt;/i&gt;huacnlee&lt;/a&gt; &lt;a href="/rei" class="user-mention" title="@rei"&gt;&lt;i&gt;@&lt;/i&gt;rei&lt;/a&gt; &lt;a href="/lgn21st" class="user-mention" title="@lgn21st"&gt;&lt;i&gt;@&lt;/i&gt;lgn21st&lt;/a&gt; &lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Fri, 20 Jun 2014 12:17:42 +0800</pubDate>
      <link>https://ruby-china.org/topics/20077</link>
      <guid>https://ruby-china.org/topics/20077</guid>
    </item>
    <item>
      <title>此条信息发自我的 Macbook，由移动硬盘驱动。</title>
      <description>&lt;p&gt;Mac 的硬盘数据线莫名其妙的挂掉了，在淘宝的买的线到来之前，只能先这样用了。除了开机慢点，Rubymotion 编译神马的速度还可以，我就忍了。&lt;/p&gt;

&lt;p&gt;看来真的需要换电脑了……&lt;/p&gt;

&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/2014/f4b6d4a3763f76380c6092b0f22401e4.png" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Mon, 05 May 2014 13:40:28 +0800</pubDate>
      <link>https://ruby-china.org/topics/19022</link>
      <guid>https://ruby-china.org/topics/19022</guid>
    </item>
    <item>
      <title>Simple Form 终完美支持 Bootstrap 3</title>
      <description>&lt;p&gt;我知道一直有兼容方案，但是 Checkbok 一直是不完美的。现在&lt;code&gt;3.1.0.rc&lt;/code&gt;已经完美支持了 Bootstrap 3，而且官方的例子也已经完美支持 Bootstrap 3。&lt;/p&gt;

&lt;p&gt;&lt;a href="http://simple-form-bootstrap.plataformatec.com.br/" rel="nofollow" target="_blank"&gt;http://simple-form-bootstrap.plataformatec.com.br/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这下，写项目，美化 Devise 的时候，终于不用感觉到头大了……&lt;/p&gt;

&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/2014/8580fa596859081b6f1887fee06c44c0.png" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Sat, 19 Apr 2014 21:05:42 +0800</pubDate>
      <link>https://ruby-china.org/topics/18717</link>
      <guid>https://ruby-china.org/topics/18717</guid>
    </item>
    <item>
      <title>CanCan 改名了，成为 CanCanCan</title>
      <description>&lt;p&gt;&lt;a href="https://github.com/ryanb/cancan/issues/994" rel="nofollow" target="_blank"&gt;https://github.com/ryanb/cancan/issues/994&lt;/a&gt;
&lt;a href="https://github.com/cancancommunity/cancancan" rel="nofollow" target="_blank"&gt;https://github.com/cancancommunity/cancancan&lt;/a&gt;&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Thu, 27 Feb 2014 10:37:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/17519</link>
      <guid>https://ruby-china.org/topics/17519</guid>
    </item>
    <item>
      <title>LaunchRocket，更容易的启动由 Homebrew 安装的服务</title>
      <description>&lt;p&gt;还在纠结那些使用 Homebrew 安装的 MySQL，Posgresql 如何启动么？
在推荐神器之前，务必介绍一个目前在用的方法：
&lt;code&gt;brew services start mysql&lt;/code&gt;
&lt;a href="http://robots.thoughtbot.com/starting-and-stopping-background-services-with-homebrew" rel="nofollow" target="_blank"&gt;http://robots.thoughtbot.com/starting-and-stopping-background-services-with-homebrew&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;当然，LaunchRocket 的方法显然更酷，比较类似于 MongoDB Preference Pane，不过是将所有的服务都集中在一处。
参考链接：
&lt;a href="http://thechangelog.com/mac-preferencepane-homebrew-launchdlaunchctl/" rel="nofollow" target="_blank"&gt;http://thechangelog.com/mac-preferencepane-homebrew-launchdlaunchctl/&lt;/a&gt;
&lt;a href="https://github.com/jimbojsb/launchrocket" rel="nofollow" target="_blank"&gt;https://github.com/jimbojsb/launchrocket&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我的 LaunchRocket：
&lt;img src="//l.ruby-china.com/photo/2014/f78d15b75c564c2c0117947ff3b15fbb.png" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Sun, 16 Feb 2014 10:45:33 +0800</pubDate>
      <link>https://ruby-china.org/topics/17287</link>
      <guid>https://ruby-china.org/topics/17287</guid>
    </item>
    <item>
      <title>用 Node-webkit 来解决企业应用浏览器兼容问题</title>
      <description>&lt;p&gt;今天晚上突然间想到的解决方法，实验完成了。&lt;/p&gt;

&lt;p&gt;项目背景：
一个网络版本的应用系统，类似企业内部使用，而非受众面广的互联网应用。使用用户基本可控。&lt;/p&gt;

&lt;p&gt;问题：
项目中整合了 Bootstrap 3 和 Reveal.js。结果，Reveal.js 不支持 IE 8 …… Bootstrap 3 的显示效果也是一团渣。
好吧，这个不是他们两个的错误。
但是，肯定，我们很难解决浏览器的这个问题，估计将来的用户群中可能还会有 IE 6 存在，强制用户升级这件事情估计不太靠谱。&lt;/p&gt;

&lt;p&gt;另外，我知道可以要求用户安装 Chorme 或者 Chrome Frame，但是，有个非常郁闷的问题，这中国的网络环境，着实让人郁闷。反正，我安装 Chrome Frame 就没有顺畅的时候。&lt;/p&gt;

&lt;p&gt;灵感：
Node-Webkit。其实这个系统一开始的要求是写单机版，无奈真的不懂单机的开发技术栈，就想着用熟悉的技术来做。后来选型：Node-Webkit+AngularJs+Bootstrap 3+WebSQL。结果，后来写的我想吐，就转为写 Rails 了。
Node-Webkit 本身就是一个 Chrome 浏览器，目前来说，相对成熟。&lt;/p&gt;

&lt;p&gt;最终，考虑到 IE 8 下效果基本成为废品，心力憔悴啊。就开始考虑有什么方法可以比较轻松的解决这个问题。&lt;/p&gt;

&lt;p&gt;后来，想到 Node-Webkit 的 Package.json 应该可以指定&lt;code&gt;URL&lt;/code&gt;而不是单纯的&lt;code&gt;file://&lt;/code&gt;，就尝试了下。&lt;/p&gt;

&lt;p&gt;Bang。可以实现，并且打包成 exe 安装包。&lt;/p&gt;

&lt;p&gt;整个 Node-Webkit 项目目录就两个文件，Package.json 和图标文件。
使用 Inno Setup 打包成安装包之后，15MB，XP 安装无压力。安装之后的大小 50MB，并且可以占据用户的开始菜单和桌面图标。（要知道很多人从来不记 URL）。建议保留 Node-Webkit 的 Frame，隐藏 Toolbar。
同时，Inno Setup 还可以定制安装界面，更好的做宣传。要知道，Inno Setup 常用来打包游戏，界面可以华丽到爆。&lt;/p&gt;

&lt;p&gt;这样，就可以将用户浏览器的升级转变为强制安装一个专用浏览器。想起了有道 hex 博客中有这样一句话&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;开发效率，如果你有过 web 前端开发经历，现在仅要求你支持最新版的 chrome 浏览器，你觉得如何？睡着了都能笑醒的事，heX 做到了；&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;顺道吐槽下，本来单机版想用有道的 heX 开发，结果，不仅文档欠缺，后期代码都从 Github 上面消失了……&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;相关链接：
&lt;a href="https://github.com/rogerwang/node-webkit" rel="nofollow" target="_blank"&gt;https://github.com/rogerwang/node-webkit&lt;/a&gt;
&lt;a href="https://github.com/rogerwang/node-webkit/wiki" rel="nofollow" target="_blank"&gt;https://github.com/rogerwang/node-webkit/wiki&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="再次声明，仅是给企业项目的浏览器兼容项目提供个思路，不适合互联网项目。"&gt;再次声明，仅是给企业项目的浏览器兼容项目提供个思路，不适合互联网项目。&lt;/h2&gt;
&lt;hr&gt;

&lt;p&gt;贴一下我的 Package.json&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://10.211.55.2:3000"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"study"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"学习系统客户端"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"keywords"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node-webkit"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"学习系统"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"toolbar"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"frame"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;960&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"mouse"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"min_width"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;780&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"min_height"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;480&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nsfc.png"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"webkit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"plugin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;真的项目里面仅有两个文件，一个是这个代码，一个就是 &lt;code&gt;nsfc.png&lt;/code&gt;。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;如果你仅仅是想解决 Chrome Frame 安装的网络问题，可以从 &lt;a href="http://www.google.com/chromeframe/eula.html?msi=true" rel="nofollow" target="_blank"&gt;http://www.google.com/chromeframe/eula.html?msi=true&lt;/a&gt; 预先下载离线安装包。&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Fri, 29 Nov 2013 04:04:25 +0800</pubDate>
      <link>https://ruby-china.org/topics/15876</link>
      <guid>https://ruby-china.org/topics/15876</guid>
    </item>
    <item>
      <title>Veewee，快速定义 Vagrant 的 box，支持各种虚拟机</title>
      <description>&lt;p&gt;一直在用 vagrant-parallels，但是针对 Parallels Desktop 的 box 非常少，&lt;a href="http://www.vagrantbox.es" rel="nofollow" target="_blank"&gt;http://www.vagrantbox.es&lt;/a&gt; 上面也没有。&lt;/p&gt;

&lt;p&gt;今天偶然在 Github 上面发现了 &lt;a href="https://github.com/mkoryak/vagrant-parallels-ubuntu-12.04-lts" rel="nofollow" target="_blank"&gt;https://github.com/mkoryak/vagrant-parallels-ubuntu-12.04-lts&lt;/a&gt; ，进而发现了 &lt;a href="https://github.com/jedi4ever/veewee" rel="nofollow" target="_blank"&gt;https://github.com/jedi4ever/veewee&lt;/a&gt; 。然后我就被 Veewee 震惊了。&lt;/p&gt;

&lt;p&gt;简单来说，Veewee 就是“Easing the building of vagrant boxes”的一个工具，支持&lt;code&gt;VirtualBox&lt;/code&gt; &lt;code&gt;VMware (Fusion)&lt;/code&gt; &lt;code&gt;KVM&lt;/code&gt; &lt;code&gt;Parallels&lt;/code&gt;四种虚拟机格式文件的导出。&lt;/p&gt;

&lt;p&gt;不过，这个还不是它最厉害的地方，最厉害的地方是它有一堆的&lt;code&gt;templates&lt;/code&gt;可以用，单纯针对&lt;code&gt;Parallels&lt;/code&gt;就有近 200 个 template，支持 CentOS 4.8 到 Ubuntu 13.10，乃至 Windows 2008 到 Windows 8。以后装虚拟机也省事了……
具体的 Template 请移步 &lt;a href="https://github.com/jedi4ever/veewee/tree/master/templates" rel="nofollow" target="_blank"&gt;https://github.com/jedi4ever/veewee/tree/master/templates&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;再者，Veewee 的配置文件中有&lt;code&gt;:boot_cmd_sequence&lt;/code&gt;，里面可以模拟一些按键，做到自动化安装。好吧，碉堡了。
还支持&lt;code&gt;:postinstall_files&lt;/code&gt;，可以放置一些后期的脚本，比如设置&lt;code&gt;vagrant&lt;/code&gt;或者安装 ruby 等等。不过，我在用 Chef-solo，所以我需要一个纯净的系统。XD&lt;/p&gt;

&lt;p&gt;对于 Veewee，我认为完全可以取代 &lt;a href="http://www.vagrantbox.es" rel="nofollow" target="_blank"&gt;http://www.vagrantbox.es&lt;/a&gt; 了，尤其适合团队配置适合自己的 Vagrant 开发环境，并同步线上环境（如果你用脚本的话）。&lt;/p&gt;

&lt;p&gt;补充一点，对于 Parallels Desktop，需要安装 parallels_sdk，链接地址： &lt;a href="http://www.parallels.com/downloads/desktop/" rel="nofollow" target="_blank"&gt;http://www.parallels.com/downloads/desktop/&lt;/a&gt; 中的 &lt;code&gt;Additional downloads for Parallels Desktop 9 for Mac &amp;gt; Parallels Virtualization SDK 9 for Mac&lt;/code&gt;&lt;/p&gt;</description>
      <author>chunlea</author>
      <pubDate>Fri, 22 Nov 2013 04:39:34 +0800</pubDate>
      <link>https://ruby-china.org/topics/15719</link>
      <guid>https://ruby-china.org/topics/15719</guid>
    </item>
  </channel>
</rss>
