<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>blackanger (blackanger)</title>
    <link>https://ruby-china.org/blackanger</link>
    <description>在论坛吹水浪费时间，有木有，以后尽量少来。。。</description>
    <language>en-us</language>
    <item>
      <title>《Rust 编程之道》预售开启</title>
      <description>&lt;h3 id="感谢大家一直以来对这本书的关注，《Rust编程之道》今天终于开始预售了。"&gt;感谢大家一直以来对这本书的关注，《Rust 编程之道》今天终于开始预售了。&lt;/h3&gt;&lt;h3 id="《Rust编程之道》介绍"&gt;《Rust 编程之道》介绍&lt;/h3&gt;
&lt;p&gt;本书跟进 Rust 2018 Edition。本书的特色：&lt;/p&gt;

&lt;p&gt;从设计哲学出发，探索 Rust 语言内在一致性 
从源码分析入手，探索 Rust 地道的编程风格 
从工程角度着手，探索 Rust 对健壮性的支持 
从底层原理开始，探索 Rust 内存安全的本质&lt;/p&gt;

&lt;p&gt;更多关于本书的介绍，大家可以参考这篇文章：&lt;a href="https://zhuanlan.zhihu.com/p/47179483" rel="nofollow" target="_blank" title=""&gt;张汉东：《Rust 编程之道》完整目录公布&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;为大家提供了样章下载：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;链接：&lt;a href="https://pan.baidu.com/s/1wWU9zPnMi1zz4JA_MTjDVQ" rel="nofollow" target="_blank" title=""&gt;百度网盘&lt;/a&gt; 提取码：yuey&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;加群交流&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;如果你想和我交流，可以加我的微信群，通过私聊方式获取我的微信号，到时候邀请进群。&lt;/p&gt;
&lt;h3 id="电子工业出版社预售地址："&gt;电子工业出版社预售地址：&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://item.jd.com/12479415.html" rel="nofollow" target="_blank" title=""&gt;《Rust 编程之道》(张汉东)【摘要 书评 试读】- 京东图书&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;现在是八四折，优惠力度还可以。官方预售大概是 2019 年 1 月 7 号开始发货。&lt;/p&gt;
&lt;h3 id="作者签名版"&gt;作者签名版&lt;/h3&gt;
&lt;p&gt;想买我签名版的朋友可以关注我的微信小店：混沌小店，也可以通过扫描下图二维码来进入店铺。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://wx1.sinaimg.cn/mw690/71684decly1fymk3xjyxtj20u01e0kjr.jpg" title="" alt="img"&gt;&lt;/p&gt;

&lt;p&gt;混沌小店 -《Rust 编程之道》签名版&lt;/p&gt;

&lt;p&gt;小店里提供了 50 份价值 15 元的优惠卷，相当于是九折优惠，包邮。因为我不是经销商，无法给大家提供更多的优惠了。如果你想要更便宜的价格，可以关注电子工业出版社官方店铺的八四折优惠。&lt;/p&gt;

&lt;p&gt;签名版发货比官方多等一到两周。&lt;/p&gt;
&lt;h3 id="样书照片"&gt;样书照片&lt;/h3&gt;
&lt;p&gt;说明：封面上有白色条纹，那是印刷质感，不是磨损。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://wx3.sinaimg.cn/mw690/71684decly1fymj6metsoj20gf0lm44e.jpg" title="" alt="img"&gt;
&lt;img src="https://wx3.sinaimg.cn/mw690/71684decly1fymj6rk4ycj20u0140u0y.jpg" title="" alt="img"&gt;
&lt;img src="https://wx3.sinaimg.cn/mw690/71684decly1fymj6wdxm2j20u0140u0y.jpg" title="" alt="img"&gt;
&lt;img src="https://wx3.sinaimg.cn/mw690/71684decly1fymj709i12j20u01407wj.jpg" title="" alt="img"&gt;
&lt;img src="https://wx2.sinaimg.cn/mw690/71684decly1fymj73vhw0j21400u0u0y.jpg" title="" alt="img"&gt;&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 28 Dec 2018 16:54:24 +0800</pubDate>
      <link>https://ruby-china.org/topics/37954</link>
      <guid>https://ruby-china.org/topics/37954</guid>
    </item>
    <item>
      <title>[已截止][Rust 周边] 胸章预订结束</title>
      <description>&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2018/63fc10eb-5273-46d2-9311-8eee4f54aeee.jpg!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;预定的人，在评论区或私信留下你们的 ID 和联系方式（qq 或 email） + 数量&lt;/p&gt;

&lt;p&gt;100 个起订，预计价格：25 元/个，不包邮噢，亲&lt;/p&gt;

&lt;p&gt;目前已满 100 个，截止到 4.28 号。&lt;/p&gt;

&lt;p&gt;到时候我会通过邮件联系大家，告知如何购买，确认信息请认准「张汉东」。&lt;/p&gt;

&lt;p&gt;Rust Logo 胸章可以定四种颜色，如果不选默认为古银：&lt;/p&gt;

&lt;p&gt;效果依次是古银、古金、古红铜、金色，大小直径 40mm ​​​​，高级尖卡帽&lt;/p&gt;

&lt;p&gt;古银
&lt;img src="https://wx3.sinaimg.cn/mw690/71684decly1fqp826ge96j20hu08aq4d.jpg" title="" alt="img"&gt;&lt;/p&gt;

&lt;p&gt;古金
&lt;img src="https://wx4.sinaimg.cn/mw690/71684decly1fqp829bbe4j21401hcahm.jpg" title="" alt="img"&gt;&lt;/p&gt;

&lt;p&gt;古红铜
&lt;img src="https://wx4.sinaimg.cn/mw690/71684decly1fqp82c3yrmj21kw23vdyx.jpg" title="" alt="img"&gt;&lt;/p&gt;

&lt;p&gt;金色
&lt;img src="https://wx4.sinaimg.cn/mw690/71684decly1fqp82e6zpsj206505mwej.jpg" title="" alt="img"&gt;&lt;/p&gt;

&lt;p&gt;请选择你的颜色&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Wed, 25 Apr 2018 14:37:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/35531</link>
      <guid>https://ruby-china.org/topics/35531</guid>
    </item>
    <item>
      <title>[老文] 怀念_why 先生——whytheluckystiff</title>
      <description>&lt;p&gt;翻到一篇老文（2010 年），有所感慨。&lt;/p&gt;

&lt;p&gt;原文在此，包括了部分图片：&lt;a href="https://www.douban.com/note/64005602/" rel="nofollow" target="_blank" title=""&gt;https://www.douban.com/note/64005602/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;下面是转载，但是没有图。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;终于到了为_why 先生写点什么的时候了。在_why 先生突然神秘消失后，我就一直想写这篇文章。但我心中又充满忐忑，毕竟我从未见过_why 先生，不认识他，甚至连他的本名都不知道。可是这个神秘人又有种难以抗拒的魅力，他的经历也有着传奇般的吸引力。好吧，那就让我通过这篇文章，来表达一个程序员对另一个程序员的最高敬意吧。&lt;/p&gt;

&lt;p&gt;事情还得从几年前说起。2004 年底，一个叫 David Heinemeier Hansson（DHH）的丹麦小伙开发了一个 Web 框架，他将其命名为 Ruby on Rails（简称 Rails）。Rails 简单易用，并融合了多种优秀设计思想，很快便震撼了软件业界。DHH 也因此荣膺由 Google/O'Reilly 联合颁布的 2005 年度最佳黑客。&lt;/p&gt;

&lt;p&gt;这股热潮渐渐波及到整个世界。2007 年在深圳，因为工作的原因，我开始接触 Ruby on Rails。Ruby on Rails 中的 Ruby，是开发 Rails 框架所用的计算机语言。Ruby 为日本人松本行弘所发明，诞生十多年来，除了日本以外，在世界其他地区知名度并不高。而随着 Rails 框架的流行，Ruby 也开始受到更多开发人员的关注，许多世界上最聪明的程序员，就是在这个时候进入 Ruby 社区。今天这篇文章的主人公_why 先生，就曾经是 Ruby 社区中最耀眼的明星之一。&lt;/p&gt;

&lt;p&gt;在我开始学习 Ruby 后，很快就为这门语言优雅精致的设计所折服。初学时除了阅读那本著名的镐头书外，也经常在网上查看文档。其中一个设计精巧的网页引起了我的注意，那是一个在线的学习指导，最神奇的是你可以在浏览器中直接执行 Ruby 代码！（去试试这个网页吧，按照屏幕下方的提示，把命令敲入到上方的窗口中，它可以让你快速掌握 Ruby 语言的基本用法）。很久以后我才知道，这也是天才_why 先生的无数杰作之一。&lt;/p&gt;

&lt;p&gt;二&lt;/p&gt;

&lt;p&gt;Ruby 有着众多精妙特性，其中最吸引我的，是它作为动态语言强大的元编程（metaprogramming）能力。在查找元编程的资料时，我有幸再次邂逅_why 先生的杰作。&lt;/p&gt;

&lt;p&gt;就是这个网页，那时我在_why 先生的个人网站上看到它——那个网站在半年多前，在_why 先生神秘失踪后便随之消失了——好在这里还保存着一份镜像。即使你对 Ruby 不感兴趣，即使你不懂编程语言，我仍然建议你去看看这个网页。
这不像是一个程序教学或示例网页，强烈的视觉冲击力，使它像是出自某个设计师的手笔。我喜欢这个页面的风格，也喜欢那些有趣的插画。后来我才知道，这都是_why 先生自己完成的。一个出色的网页设计师，或是一个出色的卡通画家，_why 先生总是可以随意切换他的众多身份，并且把每一种干得出色。&lt;/p&gt;

&lt;p&gt;他的主业自然是一个出色的 Ruby 程序员。在这个网页中，_why 先生用几十行 ruby 代码，写了一个叫"Dwemthy's array"小游戏，向我们讲述了一个“恿兔斗恶龙”的故事。去看看那些可爱的卡通插画，去听听_why 先生绘声绘色的描述，他是一个多么有趣的人啊！
我喜欢他行文的幽默笔调，他天真的诙谐以及文字中自然流露的可爱的孩子气。他像一个童心未泯的大孩子，故意用文字营造一种可怖的气氛——他就像一个悄悄站在你身后、准备吓你一大跳的坏孩子，同时还要怒力忍住才能不让自己笑出来。注意到浏览器上方的标题了吗，刻意制造的夸张效果，我想_why 先生在设计这个网页时，也一定在按奈不住地偷偷发笑吧...
看看那只兔子在漫画中说的：&lt;/p&gt;

&lt;p&gt;他的文字是极好的。想象力仿佛天马行空，文字流畅、有趣，又暗含盈盈古意；而另一些句子，除了幽默之外，似乎又有着箴言般的冷峻、精确，引人深思：
看看这个故事的开头：
“In this game, you are a rabbit who is going to die. A dragon is going to do it. ”
再来看看故事结尾的呼应：
“Oh, and none of this "I'm too young to die" business. I'm sick of that crap. I'm not going to have you insulting our undead young people. They are our future. After our future is over, that is.”&lt;/p&gt;

&lt;p&gt;从 Ruby 程序员的角度来讲，他通过这个小游戏的代码示例，教会了我 metaclass（严格说应该叫 eigenclass）的用法，教会了我 instance_eval，class_eval，教会了我 define_method，教会了我 alias。他对 Ruby 语言的掌握极其深入，这些高级特性被他信手拈来，运用得毫不造作。他的代码也极其精炼、考究，富有美感。他使用了一种全世界最有趣的教学方式，将程序、游戏、故事、卡通完美地融合在了一起，使这个网页成了一件艺术品。
老实说，我被深深震撼了，我从来不知道世界上有这么有趣的人。我从来不知道代码可以这样来写，程序教学可以这样来完成。我也喜欢这个“勇兔斗恶龙”的故事，事实上，我欣赏他的每一句话，每一副插画。&lt;/p&gt;

&lt;p&gt;在_why 先生离开后，他在“恿兔斗恶龙”开头和结尾写下的寓言般的句子成了一个隐喻。后来我才知道，这只是_why 先生所写的《Ruby 入门（插画版）》中的一章而已。他的才华光彩夺目。&lt;/p&gt;

&lt;p&gt;三&lt;/p&gt;

&lt;p&gt;没有人知道_why 先生的真名。whytheluckystiff 是他的常用 id，也是他失踪前个人网站&lt;a href="http://whytheluckystiff.net_why%EF%BC%88twitter%EF%BC%89%E5%92%8Cwhy%EF%BC%88github%EF%BC%89%E4%B9%9F%E6%98%AF%E4%BB%96%E7%9A%84%E5%B8%B8%E7%94%A8id%E3%80%82%E5%9C%A8Ruby%E7%A4%BE%E5%8C%BA%EF%BC%8C%E4%BA%BA%E4%BB%AC%E4%B8%80%E8%88%AC%E7%94%A8_why%E6%9D%A5%E7%A7%B0%E5%91%BC%E4%BB%96%E3%80%82" rel="nofollow" target="_blank"&gt;http://whytheluckystiff.net_why（twitter）和why（github）也是他的常用id。在Ruby社区，人们一般用_why来称呼他。&lt;/a&gt;的域名。&lt;/p&gt;

&lt;p&gt;Ruby 语言本身的特点（动态语言，无需编译，基于源代码运行），赋予了 Ruby 社区开放、互助的特质。Ruby 社区中大部分的程序都开源，大部分作者从这些作品中得不到任何金钱回报；许多杰出的作品，仅仅是凭借兴趣、好奇心和追求完美的态度来完成的。而 Ruby 社区能回馈给这些创造者的，也不过是在社区或软件业界的一点名望罢了。在这样的社区中，程序水平的高低、对社区贡献的大小就会成为某个 id 影响力的决定因素。
从我开始学习 Ruby，到_why 先生从 Ruby 社区中离开，一共有两年多的时间。依我所见，_why 先生对社区仅能回馈的这点名望也并不看重。从他选择隐形埋名、并且从不透露自己的真实身份便不难做出判断。他像是一个少言寡语的人，只是不停地创作、创作、创作... 他是一个高产得有些吓人的天才。&lt;/p&gt;

&lt;p&gt;我用过_why 先生的很多作品；事实上，只要在 Ruby 社区中混过一段时间，就很难不接触到_why 先生写的代码。
前面我提到过_why 先生创作的 try ruby 网页和 Ruby 入门（插画版），那是_why 先生送给初学者的最好礼物。
让我想想还用过_why 先生的哪些作品：
RedCloth: Textile 语法的 Ruby 实现，现在也还经常在工作中、在 Redmine 中用到。
hpricot: 一个轻量的 html 解析器，在 nokogiri 出现之前，也是我们经常在工作中用到的。
shoes: 用 Ruby 来创建 GUI 应用的工具。
camping: 一个轻量级的 Web 框架。我记得当初看到 camping 代码的震惊，我觉得_why 先生在其中运用的各种技巧，简直可以用鬼斧神工来形容。camping 的代码教会了我很多东西，几年前我也曾试着模仿它写过一个小型的 Web 框架。
markaby: 轻量标记语言，也是 camping 框架中 view 默认使用的标记语言。
……&lt;/p&gt;

&lt;p&gt;_why 先生确实是一个创造力极其旺盛、极其高产的天才。在他神秘消失后，在他将自己的众多作品“付之一炬”后，有人在 github 上用从前搜集的_why 先生的代码建立了一个映像。我刚才又去确认了一下，目前这个映像包含 38 个 repos。在我看来，如果一个程序员能够发布 5 个对社区有用的 repos 就已经算很高产了——用这种标准来看，_why 先生同时维护着几十个 repos 是怎样一种概念！
_why 先生不止高产，他作品的质量也同样卓越。像 RedCloth，hpricot，shoes 这样出色的 gem，都给 Ruby 社区带来过巨大的帮助。在数量和外在的质量之外，他代码的品质也同样优秀。我阅读过他的许多代码，他教会了我很多东西，他的代码简洁、精炼、结合 Ruby 语言的强大特性，许多技巧的使用别具匠心。像 camping 这样带点炫技性质的玩票之作，在我初接触到代码时简直感到匪夷所思。毫不夸张地说，_why 先生的许多代码，同样达到了艺术品的境界，使得阅读和模仿都成了一种享受。&lt;/p&gt;

&lt;p&gt;从前_why 先生的个人网站&lt;a href="http://whytheluckystiff.net/_why%E5%85%88%E7%94%9F%E5%8F%91%E5%B8%83%E5%9C%A8%E4%B8%8A%E9%9D%A2%E7%9A%84%E5%90%84%E7%A7%8D%E4%BD%9C%E5%93%81%EF%BC%8C%E4%BB%A3%E7%A0%81%E3%80%81%E6%BC%AB%E7%94%BB%E3%80%81%E6%96%87%E7%AB%A0%E7%AD%89%E7%AD%89%E3%80%82%E5%9C%A8%E7%BC%96%E7%A8%8B%E6%84%9F%E5%88%B0%E6%97%A0%E8%81%8A%E7%94%9A%E8%87%B3%E8%8B%A6%E9%97%B7%E6%97%B6%EF%BC%8C%E9%82%A3%E4%B9%9F%E6%98%AF%E6%88%91%E9%87%8D%E6%96%B0%E5%AF%BB%E6%89%BE%E7%81%B5%E6%84%9F%E7%9A%84%E6%9D%A5%E6%BA%90%E3%80%82%E5%BE%88%E5%8F%AF%E6%83%9C%EF%BC%8C%E5%9C%A8_why%E5%85%88%E7%94%9F%E7%A5%9E%E7%A7%98%E5%A4%B1%E8%B8%AA%E5%90%8E%EF%BC%8C%E8%BF%99%E4%B8%AA%E7%BD%91%E7%AB%99%E4%B9%9F%E9%9A%8F%E4%B9%8B%E6%B6%88%E5%A4%B1%E4%BA%86%E3%80%82" rel="nofollow" target="_blank"&gt;http://whytheluckystiff.net/_why先生发布在上面的各种作品，代码、漫画、文章等等。在编程感到无聊甚至苦闷时，那也是我重新寻找灵感的来源。很可惜，在_why先生神秘失踪后，这个网站也随之消失了。&lt;/a&gt;我是经常访问的。我喜欢&lt;/p&gt;

&lt;p&gt;四&lt;/p&gt;

&lt;p&gt;终于要说到_why 先生的神秘消失了。半年多以前的一天，_why 突然从世界上消失了。有一天，人们突然发现，_why 先生的个人网站无法访问了，接下来人们发现他删除了自己的 twitter 帐号、github 帐号，&lt;a href="http://poignantguide.net/http://hackety.org/http://shoooes.net/%EF%BC%8C%E8%BF%99%E4%BA%9B_why%E5%85%88%E7%94%9F%E7%BB%B4%E6%8A%A4%E7%9A%84%E7%BD%91%E7%AB%99%EF%BC%8C%E4%B9%9F%E9%83%BD%E9%9A%8F%E4%B9%8B%E7%AA%81%E7%84%B6%E6%B6%88%E5%A4%B1%E4%BA%86%E3%80%82%E6%B2%A1%E6%9C%89%E4%BA%BA%E7%9F%A5%E9%81%93_why%E5%85%88%E7%94%9F%E7%AA%81%E7%84%B6%E7%A6%BB%E5%8E%BB%E7%9A%84%E7%90%86%E7%94%B1%EF%BC%8C%E5%B0%B1%E5%83%8F%E4%BB%8E%E6%9D%A5%E6%B2%A1%E6%9C%89%E4%BA%BA%E7%9F%A5%E9%81%93%E4%BB%96%E7%9A%84%E7%9C%9F%E5%AE%9E%E8%BA%AB%E4%BB%BD%E3%80%82%E4%BD%86%E8%BF%99%E6%A0%B7%E4%B8%80%E4%BD%8D%E8%B6%85%E7%BA%A7%E6%98%8E%E6%98%9F%E7%9A%84%E7%A6%BB%E5%8E%BB%EF%BC%8C%E5%AF%B9%E6%95%B4%E4%B8%AA%E7%A4%BE%E5%8C%BA%E9%83%BD%E4%B8%8D%E5%95%BB%E4%BA%8E%E4%B8%80%E9%81%93%E6%99%B4%E5%A4%A9%E9%9C%B9%E9%9B%B3%E2%80%94%E2%80%94%E4%B9%9F%E6%9C%89%E4%BA%BA%E8%87%AA%E6%88%91%E5%AE%89%E6%85%B0%E5%BC%8F%E5%9C%B0%E8%AF%B4%E5%88%B0%EF%BC%8C%E4%B9%9F%E8%AE%B8_why%E5%85%88%E7%94%9F%E5%8F%AA%E6%98%AF%E4%B8%B4%E6%97%B6%E7%A6%BB%E5%BC%80%EF%BC%8C%E4%B9%9F%E8%AE%B8%E4%BB%96%E5%BE%88%E5%BF%AB%E4%BE%BF%E4%BC%9A%E5%9B%9E%E6%9D%A5%E5%90%A7%E3%80%82" rel="nofollow" target="_blank"&gt;http://poignantguide.net/http://hackety.org/http://shoooes.net/，这些_why先生维护的网站，也都随之突然消失了。没有人知道_why先生突然离去的理由，就像从来没有人知道他的真实身份。但这样一位超级明星的离去，对整个社区都不啻于一道晴天霹雳——也有人自我安慰式地说到，也许_why先生只是临时离开，也许他很快便会回来吧。&lt;/a&gt;、
半年多过去了，_why 先生一直没有回来。&lt;/p&gt;

&lt;p&gt;很多人在推测_why 先生离开的原因。有人推测_why 先生的离开，来自他的作品 hpricot 被后起之秀 nokogiri 超越时产生的失落，他们甚至引用了_why 先生在 twitter 上说过的一段话：
“programming is rather thankless. u see your works become replaced by superior ones in a year. unable to run at all in a few more.”
但选择隐姓埋名、似乎从未看重过社区声望的_why 先生，真的会是一个如此小气的人吗？&lt;/p&gt;

&lt;p&gt;07 年底的时候，同样有一位超级明星离开 Ruby 社区，并同样引发了一场地震。他叫 Zed Shaw，也是一位让我欣赏、佩服的程序员。Zed Shaw 是 Web 服务器 Mongrel 的作者，Mongrel 的出现大大推进了 Rails 部署的进程。
Zed Shaw 才华横溢，但个性太过鲜明，在 Ruby 社区的一段时间中，和不少大佬产生了摩擦，最后毅然决然地退出，并且在退出前发文将 Ruby 社区、社区中的几位重量级人物狠狠痛骂了一番。&lt;/p&gt;

&lt;p&gt;在_why 先生突然神秘消失后，他的离开使人们重新想起了 Zed Shaw。有人甚至在打趣说，也许_why 先生就是 Zed Shaw 的一个化名。但_why 先生的离去是如此沉默，在他决定离开他深爱的 Ruby 语言和社区时，他没有发表过任何抱怨或攻击性的言论。他留给社区的，只有一个虚幻身份掩映下的巨大背影。
我还听到过这样的说法，他们说_why 先生和 Zed Shaw 都是天才，_why 先生就像是一个温和、善良版的 Zed Shaw。在我怀念_why 先生乃至 Zed Shaw 时，我也会陷入迷思般地推测，他们是否就是卡尔维诺笔下那个《分成两半的子爵》？&lt;/p&gt;

&lt;p&gt;五&lt;/p&gt;

&lt;p&gt;_why 先生走得很决绝。在他决定离开后，他删除了自己的所有网站，删除了自己的各个帐号，又删除了自己的全部作品。
在_why 先生神秘消失后，Ruby 社区、乃至整个业界都在谈论这位天才的离去。各种关于他的讨论铺天盖地。人们一边猜测他离去的原因，一边把最热烈的赞颂奉献给他。那些天，在 reddit 和 Hacker News 上满屏都是关于 _why 的话题，有人说这是从未出现过的景象。&lt;/p&gt;

&lt;p&gt;在_why 先生离开前，他毁掉了自己的所有作品，这种行为令很多人难以接受、难以理解。在我重新查看那些评论时，Hacker News 上的一段话引起了我的注意：
“Though it would be considered a bit rude by many, somewhere I understand the philosophy of _why. It would be better to kill something fast than watch it wither away and die.[especially when they are close to your heart].”
这段话同样深深打动了我，甚至让我追忆起那种心碎的感觉。也许对自己深爱的人或事物，那些真正贴近你心灵的人或事物，唯有通过这种决绝的方式，才能避免眼看它渐渐枯萎、渐渐凋零时产生的更大痛苦。&lt;/p&gt;

&lt;p&gt;在_why 先生离开并删除自己的全部作品后，人们用从前保留的资料，一件件地恢复他的创作。github 上有了 why 先生的代码镜像，人们将他的代码称为可运行的诗句（_why's executable poetry）。他的《Ruby 入门（插画版）》也有了新的镜像。有人在维基百科上创建了一个关于他的词条，现在那是一个 pagerank 高达 6 的网页。
仍然有人在猜测着_why 先生的真实身份。但最终，这些试图“拆穿”_why 先生真实身份的讨论慢慢湮灭了，_why 先生隐姓埋名的意愿得到了人们的尊重。&lt;/p&gt;

&lt;p&gt;我想很多人都对_why 先生心存感激，他是一个对社区有过巨大贡献的人。我也对_why 先生充满感激，他的代码曾教会了我很多东西。
_why 先生还是一个艺术家气质的人，他的漫画、他的文章、他的代码都具有艺术品的气质，按照维基百科上的说法，他还是一支叫“The Child Who Was A Keyhole”的乐队的成员。
从他的文字中，从他的漫画和他编纂的一个个小故事中，我还感受到他的幽默感，他的理性、温情、善良，以及不经意流露出的孩子气。阅读他的文章、他的代码、他的漫画都给我以美的享受。
这所有的一切，这些在一个远在中国的程序员身上，激起了一种复杂的奇妙的情感，使得他今天写这篇文章来怀念一个自己从未见过、也并不认识的人。&lt;/p&gt;

&lt;p&gt;在_why 先生离开后，人们长久地怀念他、追忆他是有原因的。
王小波曾经说过，人的一生中，应该认识一些有趣的人，做出一些有趣的事情。_why 先生的代码、他的文章、他的漫画，那是我读到的最有趣的程序员作品。他也是我知道的世界上最有趣的程序员之一。
王小波还说过，一个人只拥有此生此世是不够的，他还应该拥有诗意的世界。在我看来，_why 先生拥有各种充满诗意的作品，他的缄默、他的隐姓埋名也是有诗意的；最后，他让自己的离开也充满诗意。&lt;/p&gt;

&lt;p&gt;在_why 先生离开后，有人搜集了_why 先生的 tweets，其中有这样一条让我特别喜欢：
“when you don't create things, you become defined by your tastes rather than ability. your tastes only narrow &amp;amp; exclude people. so create.”&lt;/p&gt;

&lt;p&gt;So create.&lt;/p&gt;

&lt;p&gt;附录 A（链接）
维基百科:
&lt;a href="http://en.wikipedia.org/wiki/Why_the_lucky_stiff" rel="nofollow" target="_blank"&gt;http://en.wikipedia.org/wiki/Why_the_lucky_stiff&lt;/a&gt;
rubyinside:
&lt;a href="http://www.rubyinside.com/why-the-lucky-stiff-links-2333.html" rel="nofollow" target="_blank"&gt;http://www.rubyinside.com/why-the-lucky-stiff-links-2333.html&lt;/a&gt;
&lt;a href="http://www.rubyinside.com/why-the-lucky-stiff-is-missing-2278.html" rel="nofollow" target="_blank"&gt;http://www.rubyinside.com/why-the-lucky-stiff-is-missing-2278.html&lt;/a&gt;
github:
&lt;a href="http://github.com/whymirror" rel="nofollow" target="_blank"&gt;http://github.com/whymirror&lt;/a&gt;
&lt;a href="http://github.com/why" rel="nofollow" target="_blank"&gt;http://github.com/why&lt;/a&gt;
Hacker News:
&lt;a href="http://news.ycombinator.com/item?id=773920" rel="nofollow" target="_blank"&gt;http://news.ycombinator.com/item?id=773920&lt;/a&gt;
&lt;a href="http://news.ycombinator.com/item?id=773106" rel="nofollow" target="_blank"&gt;http://news.ycombinator.com/item?id=773106&lt;/a&gt;
reddit:
&lt;a href="http://www.reddit.com/r/programming/comments/9c5on/where_is_why/" rel="nofollow" target="_blank"&gt;http://www.reddit.com/r/programming/comments/9c5on/where_is_why/&lt;/a&gt;
&lt;a href="http://www.reddit.com/r/programming/comments/9c5u4/this_is_a_sad_day_why_disappears/" rel="nofollow" target="_blank"&gt;http://www.reddit.com/r/programming/comments/9c5u4/this_is_a_sad_day_why_disappears/&lt;/a&gt;
Free Mind:
&lt;a href="http://blog.pluskid.org/?p=373" rel="nofollow" target="_blank"&gt;http://blog.pluskid.org/?p=373&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;附录 B（写完本文的一点感想）&lt;/p&gt;

&lt;p&gt;进入程序员这个行业以来，我常感受到中国的程序员和国外优秀程序员的巨大差距。在金字塔的顶端，中国的数字英雄们大概很难达到 Bill Gates、Jobs 那样的境界。另一方面，在金字塔的底端，我们与国外优秀的程序员差距更大。
在我们这儿，程序员还被看作三十岁前吃青春饭的一个职业，或者走向管理岗位的一个跳板；殊不知，国外四五十岁的优秀程序员大有人在，那些著名公司的 fellow 无论是收入和地位，也并不见得比管理层差。
阅读国外优秀程序员的代码让我觉得是一种享受。像微软、Google 公开的一些代码，像 Matz、_why 先生这些人的代码，非常工整、简洁，一丝不苟，确实可以用欣赏艺术品的眼光去审视。而就我所知，就我看过的国内某些大公司、大型软件的代码，完全可以用一塌糊涂来形容，那完全是人力堆砌的结果，没有任何美感。
有时看国外程序员写的书，在作者的自我介绍中，我经常看到作者说自己在业余时间是一个音乐家、一个画家、或者是一个木匠。_why 先生的业余身份就包括了乐队成员、漫画家、作家等等，Zed Shaw 也是一个杰出的吉他手和作家。正是这些程序员具有的艺术气质，赋予他们的代码美感，赋予他们创作的软件以美感。Coding 本质上也是一门手艺 (craft)，我相信这些都是相通的，这些都会有潜移默化的影响。所以中国的程序员中也很难出现_why 先生这样的大师。
但这一切又该指责谁呢，指责中国的程序员只会埋头做事，不会抬头看一看天空吗？但是现在的社会能给普通程序员抬头看天空的机会吗？功利、浮躁的环境，应试教育的巨大伤痕，高额的房价和生活成本，这一切都压得普通程序员喘不过起来，只能低头向着地面，哪里还敢想象甚至奢望诗意的生活？
在中国，我对程序员这个行业是悲观的。&lt;/p&gt;

&lt;p&gt;附录 C（Ruby 入门指导）&lt;/p&gt;

&lt;p&gt;——我推荐你学习 Ruby 这门语言。
——我是文科生，我也能学会吗？
——当然能，_why 先生说过，连婴儿都能学会 Ruby！&lt;/p&gt;

&lt;p&gt;——可我对编程一点都不敢兴趣啊。
——给你看一个 PPT 吧，希望你会改变主意。&lt;/p&gt;

&lt;p&gt;Q: Why should I learn a new language?&lt;/p&gt;

&lt;p&gt;Q: Why so many languages?&lt;/p&gt;

&lt;p&gt;Q: Why Ruby?&lt;/p&gt;

&lt;p&gt;孟岩的一段话
孟岩的一段话&lt;/p&gt;

&lt;p&gt;——好吧，我决定开始学习 Ruby，但我该如何开始呢？&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;首先，去试试_why 先生的 try ruby 程序。&lt;/li&gt;
&lt;li&gt;安装 Ruby 环境。Windows 用户点击这里下载后安装，Linux、Mac、BSD 用户请使用各自的安装命令 (apt-get、zypper、yum 等等）安装。&lt;/li&gt;
&lt;li&gt;去 Ruby 官方网站上看看 Ruby 入门文档，去看看_why 先生的《Ruby 入门（插画版）》，还可以买一本 TRPL 或镐头书作为参考。&lt;/li&gt;
&lt;li&gt;Try &amp;amp;&amp;amp;  Try again.&lt;/li&gt;
&lt;li&gt;Enjoy &amp;amp;&amp;amp; Create.&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 29 Dec 2017 20:39:55 +0800</pubDate>
      <link>https://ruby-china.org/topics/34793</link>
      <guid>https://ruby-china.org/topics/34793</guid>
    </item>
    <item>
      <title>使用 Goliath 1.0 实现高性能微服务 API 完整模板</title>
      <description>&lt;p&gt;今天没事翻了翻以前做的项目，发现此项目为多年前基于 Goliath1.0 + Grape 所做项目，（作为手机 APP 后台 API 服务线上稳定运行一年多，后来因为手机 app 和网站分开维护比较麻烦，后将其合并到 Rails 项目中将其下线）。 &lt;/p&gt;

&lt;p&gt;因为 Goliath 并没有提供一个统一的项目结构，故抽离的模板，今天分享出来给需要的人，可以参考此模板方便的实现 API 微服务。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ZhangHanDong/goliath-api-template" rel="nofollow" target="_blank" title=""&gt;项目地址&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;使用 Goliath 1.0 实现高性能微服务 API 完整模板（仅供参考）&lt;/p&gt;

&lt;p&gt;支持：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;异步 Rack Middleware&lt;/li&gt;
&lt;li&gt;类 Rails 的项目目录结构，方便开发&lt;/li&gt;
&lt;li&gt;自扩展的 Goliath 命令，比如 goliath console/ goliath start /goliath db 等，按需修改&lt;/li&gt;
&lt;li&gt;支持 em-synchrony 异步 http remote request 方法（查看 lib/tools/http_base.rb）&lt;/li&gt;
&lt;li&gt;增加了 Docker 化文件 (需要自行按需修改)&lt;/li&gt;
&lt;li&gt;支持 Jbuilder 并且 支持 json cache（查看 lib/tools/json_cache.rb 需要自己定义）&lt;/li&gt;
&lt;li&gt;支持异步任务&lt;/li&gt;
&lt;li&gt;支持 capistrano 部署&lt;/li&gt;
&lt;li&gt;支持 paperclip 文件上传（查看 config/initializes/paperclip.rb）&lt;/li&gt;
&lt;li&gt;支持国际化、本地时区&lt;/li&gt;
&lt;li&gt;其他（比如，可以自己配置 Grape Entity 替换 jbuilder 等）&lt;/li&gt;
&lt;/ol&gt;</description>
      <author>blackanger</author>
      <pubDate>Wed, 14 Jun 2017 20:54:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/33233</link>
      <guid>https://ruby-china.org/topics/33233</guid>
    </item>
    <item>
      <title>Ruby + OMR JIT 简介</title>
      <description>&lt;p&gt;此文为翻译，&lt;a href="https://developer.ibm.com/open/2016/11/18/introducing-ruby-jit/" rel="nofollow" target="_blank" title=""&gt;原文&lt;/a&gt;在此&lt;/p&gt;

&lt;p&gt;首发于，知乎专栏：&lt;a href="https://zhuanlan.zhihu.com/p/24113974" rel="nofollow" target="_blank" title=""&gt;Ruby+OMR JIT 简介&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;利益相关： &lt;a href="https://ruby-china.org/topics/31724" title=""&gt;《Ruby 源码剖析》现已上市！&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="正文"&gt;正文&lt;/h2&gt;
&lt;p&gt;前不久，我开源了&lt;a href="https://github.com/rubyomr-preview/rubyomr-preview" rel="nofollow" target="_blank" title=""&gt; Ruby+OMR JIT 编译器&lt;/a&gt;这篇文章中提到的&lt;a href="https://github.com/rubyomr-preview/rbjitglue" rel="nofollow" target="_blank" title=""&gt; Ruby JIT glue &lt;/a&gt;，为此我深感荣幸。&lt;/p&gt;

&lt;p&gt;该代码（&lt;a href="https://github.com/rubyomr-preview/ruby" rel="nofollow" target="_blank" title=""&gt;适度修改过的 CRuby VM 版本&lt;/a&gt;和&lt;a href="https://github.com/eclipse/omr/" rel="nofollow" target="_blank" title=""&gt;Eclipse OMR&lt;/a&gt;的组合）展示了我们如何向 CRuby 添加一个简单的 JIT 编译器。&lt;/p&gt;

&lt;p&gt;本文会涉及我在 2015 年 12 月 RubyKaigi  ( &lt;a href="https://www.youtube.com/watch?v=EDxoaEdR-_M" rel="nofollow" target="_blank" title=""&gt;Video&lt;/a&gt; ,  &lt;a href="http://www.slideshare.net/MatthewGaudet/experiments-in-sharing-java-vm-technology-with-cruby" rel="nofollow" target="_blank" title=""&gt;Slides&lt;/a&gt; ) 的&lt;a href="http://rubykaigi.org/2015/presentations/MattStudies?cm_mc_uid=90162356470714696264613&amp;amp;cm_mc_sid_50200000=1480639232" rel="nofollow" target="_blank" title=""&gt;演讲&lt;/a&gt;内容，但是这次我将展示源码。&lt;/p&gt;

&lt;p&gt;该文专注于 JIT 技术，然而我们在 GitHub 上的 VM 已经被修改为使用 OMR 的垃圾收集技术。有关更多的内容，请参阅 Craig Lehman 和 Robert Young 在 RubyKaigi 上所做的演讲，&lt;a href="http://rubykaigi.org/2015/presentations/youngrw_CraigLehmann?cm_mc_uid=90162356470714696264613&amp;amp;cm_mc_sid_50200000=1480639232" rel="nofollow" target="_blank" title=""&gt;It's dangerous to GC alone. Take this!&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id="哲学"&gt;哲学&lt;/h3&gt;
&lt;p&gt;OMR 项目基于一个前提：即许多语言运行时实现基本上是非常相似的，哪怕是完全无法类比的语言。&lt;/p&gt;

&lt;p&gt;该理念决定了 OMR 被构造为语言独立的大核心，通过依赖于语言的“胶水（glue）”，链接到实际的语言实现中。&lt;/p&gt;

&lt;p&gt;对于 Ruby JIT 来说，我们的“胶水”分为两个部分：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;修改 Ruby VM，以便于加载 JIT 编译对象，并导出某些例程（译注：让 VM 可以对外提供服务的接口），以便于 JIT 可以生成对 VM 的调用和使用 VM 的功能&lt;/li&gt;
&lt;li&gt; 适配器代码———— 即 GitHub 上 rbjitglue 项目的内容——是专门用于 Ruby 的语言独立的 OMR 编译器代码（称为 Testarossa）。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;我们尽最大的努力尽量最小化第一部分，因为我们想展示一个相对低触摸（low-touch）的 JIT 添加。&lt;/p&gt;

&lt;p&gt;我们一直希望 Ruby 社区最终可以采用 OMR JIT 作为 Ruby 的 JIT 技术，所以尽量使 VM 保持不变很重要，没有人喜欢维护这些像异形一样的补丁。这个决定限制了编译器技术的某些部分，但是我们可以跳过它（有些东西我们需要独立开发！）&lt;/p&gt;
&lt;h3 id="修改 CRuby VM"&gt;修改 CRuby VM&lt;/h3&gt;
&lt;p&gt;在运行 JIT 代码之前，我们需要在 VM 和 JIT 编译器之间提供一个接口。&lt;/p&gt;

&lt;p&gt;在我们的实现中，我们在 Init_BareVM 中增加了 vm_jit_init 调用。该函数（&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/vm_jit.c#L35" rel="nofollow" target="_blank" title=""&gt;实现于 vm_jit.c 中&lt;/a&gt;）加载 JIT DLL 并且填充一组函数指针的结构。通过这些函数指针来建立 JIT 和 VM 的通信，VM 可以使用这些函数指针（&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/vm_jit.c#L73" rel="nofollow" target="_blank" title=""&gt;init_f, terminate_f, compile_f 和 dispatch_f&lt;/a&gt;）来调用 JIT 方法。同样，JIT 也能调用 VM 方法，或者通过使用&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/vm_jit.c#L97" rel="nofollow" target="_blank" title=""&gt;存储于 JIT 回调结构中的函数指针&lt;/a&gt;来生成对 VM 方法的调用。稍后我们会再看这个回调结构。&lt;/p&gt;

&lt;p&gt;另一个重要的连接是 Ruby VM 使用的全局变量。我们需要将这些地址传递给 Ruby JIT，这份工作是由&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/jit.h#L100" rel="nofollow" target="_blank" title=""&gt;全局结构体&lt;/a&gt;来完成的，该结构体被填充以后就传递给 vm_jit_init。&lt;/p&gt;
&lt;h4 id="编译控制"&gt;编译控制&lt;/h4&gt;
&lt;p&gt;何时编译方法，即为编译控制。&lt;/p&gt;

&lt;p&gt;生产 JIT 编译器有非常复杂的试探式方法来管理启动速度，提升和峰值吞吐量之间的权衡。&lt;/p&gt;

&lt;p&gt;在 Ruby JIT 中，我们做了一个更为简单的选择：计算编译（counted compilation）。每个方法都有与之相关的计数器。方法运行时，计数器递减，到达 0 值时，该方法被编译完成。&lt;/p&gt;

&lt;p&gt;编译控制的注入与 VM 调用 JIT 编译方法方式紧密的结合了起来。&lt;/p&gt;
&lt;h4 id="JIT 编译方法调度"&gt;JIT 编译方法调度&lt;/h4&gt;
&lt;p&gt;OMR Ruby JIT 对 JIT 方法采用了一个非常简单的调用约定。JIT 生成的方法&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/jit.h#L117" rel="nofollow" target="_blank" title=""&gt;只需要一个参数&lt;/a&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef VALUE (*jit_method_t)(rb_thread_t*);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;方法的所有其他信息都从编译代码的线程参数中去检索。&lt;/p&gt;

&lt;p&gt;Ruby VM 的核心解释器循环有一些轻微修改，以便支持调用这些编译体。&lt;/p&gt;

&lt;p&gt;一般来说，解释器通过调用&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/vm_exec.c#L51" rel="nofollow" target="_blank" title=""&gt;vm_exec_core&lt;/a&gt;来启动核心解释器循环调用。&lt;/p&gt;

&lt;p&gt;为了让我们检查是否可以使用 JIT 编译体，我们把该函数&lt;a href="http://martinfowler.com/bliki/TwoHardThings.html" rel="nofollow" target="_blank" title=""&gt;聪（中）明（二）&lt;/a&gt;的命名替换为了&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/vm.c#L1486" rel="nofollow" target="_blank" title=""&gt;vm_exec2&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;vm_exec2&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/vm.c#L1442" rel="nofollow" target="_blank" title=""&gt;非常简单&lt;/a&gt;:&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;static inline VALUE
vm_exec2(rb_thread_t *th, VALUE initial)
{
    VALUE result;
    if (VM_FRAME_TYPE(th-&amp;gt;cfp) != VM_FRAME_MAGIC_RESCUE &amp;amp;&amp;amp; 
        VM_FRAME_TYPE_FINISH_P(th-&amp;gt;cfp) &amp;amp;&amp;amp; 
        vm_jitted_p(th, th-&amp;gt;cfp-&amp;gt;iseq) == Qtrue) { 
      result = vm_exec_jitted(th);
    } else { 
      result = vm_exec_core(th, initial);
    }
    return result;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该代码简单归结为两点：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;只要帧是正确的类型（代码里给出的 JIT 方法勿须理解），并且有一个 JIT 体，就可调用它获取结果。&lt;/li&gt;
&lt;li&gt;否则回到 vm_exec_core 继续解释该帧。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="使编译器适配Ruby VM"&gt;使编译器适配 Ruby VM&lt;/h3&gt;
&lt;p&gt;要想把 OMR JIT 编译器添加到语言中，最基本的部分是如何将该语言的源码转换为 JIT 编译器的中间表示（IR, Intermediate Representation）。&lt;/p&gt;

&lt;p&gt;Testarossa 的中间表示叫做树（虽然它们实际上叫 Directed-Acyclic-Graphs【有向无环图】，可惜历史的能量太强）。该树中的程序展示包含了三个主要元素：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;节点表示一个值。节点是可以产生值的原始操作（比如 lconst 10 或 lload valueInMemory），或者是复合操作，比如 add 操作，可以消费子节点来产生结果。节点有数据类型，操作将会需要并产生类型。例如，lconst 产生一个‘long’值，对 Testarossa 来说，是一个 64 位整数。aladd 会从地址的子节点和 long 类型产生一个’address’类型值。&lt;/li&gt;
&lt;li&gt;TreeTops 用于树的计算。它们是双向链表，并用于控制程序的顺序，节点树内的操作顺序无关紧要，只作用于 TreeTops 之间。在树的节点之间评估顺序很重要，我们可以通过“锚定”树节点下的节点来强制排序。&lt;/li&gt;
&lt;li&gt;TreeTops 在 BasicBlocks 中互相连接，定义了程序的控制流。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;所以，为了 JIT 编译 Ruby，我们不得不把下面的代码：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def foo(a, b)
  a + b 
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;转换到树中。在 Testarossa 中，我们把这个过程称作 IL 生成。&lt;/p&gt;
&lt;h4 id="Ruby中的IL生成"&gt;Ruby 中的 IL 生成&lt;/h4&gt;
&lt;p&gt;幸运的是，我们不必处理 Ruby 代码的解析。CRuby 解释器已经为我们做了这部分工作。自 Ruby1.9 开始，Ruby 就一直使用基于字节码的解释器，因此 Ruby 代码是被解析为字节码再进行解释。你可以使用 RubyVM :: InstructionSequence.dump 方法查看字节码：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$cat test.rb
def foo(a, b)
    a + b
end
$ ruby -e "puts RubyVM::InstructionSequence.compile_file('test.rb').disasm"
# &amp;lt;snipped iseq for main&amp;gt;  
&amp;lt;RubyVM::InstructionSequence:foo@t.rb&amp;gt;=======================
local table (size: 3, argc: 2 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 3] a&amp;lt;Arg&amp;gt;     [ 2] b&amp;lt;Arg&amp;gt;     
0000 trace            8                                               (   1)
0002 trace            1                                               (   2)
0004 getlocal_OP__WC__0 3
0006 getlocal_OP__WC__0 2
0008 opt_plus         &amp;lt;callinfo!mid:+, argc:1, ARGS_SKIP&amp;gt;
0010 trace            16                                              (   3)
0012 leave                                                            (   2)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;所以，要生成 Ruby 的树，我们可以解析方法产生的字节码，而不是直接解析源码。在 rbjitglue 中，这部分工作由&lt;a href="https://github.com/rubyomr-preview/rbjitglue/blob/master/ruby/ilgen/RubyIlGenerator.cpp" rel="nofollow" target="_blank" title=""&gt;RubyIlGenerator.cpp&lt;/a&gt;文件来完成。&lt;/p&gt;

&lt;p&gt;Ruby 所遵循的 Testarossa 的基本字节码 IL 生成方案假定每个字节码对应至多一个基本块（block）。因此，基本的块数组会被创建，然后沿着字节码经历“抽象解释过程”，生成树，再放到基本块中。抽象解释的意思是，把 IL 生成器生成代码的过程比作解释器。&lt;/p&gt;

&lt;p&gt;当检测到字节码级别的跳转（jump）时，相应的目的地字节码的树级跳转的基本块也会被生成。&lt;/p&gt;

&lt;p&gt;大部分工作最终是在&lt;a href="https://github.com/rubyomr-preview/rbjitglue/blob/eb802a5/ruby/ilgen/RubyIlGenerator.cpp#L732" rel="nofollow" target="_blank" title=""&gt;RubyIlGenerator :: indexedWalker&lt;/a&gt;内部完成的。其核心，是一个巨大的&lt;a href="https://github.com/rubyomr-preview/rbjitglue/blob/eb802a5/ruby/ilgen/RubyIlGenerator.cpp#L762" rel="nofollow" target="_blank" title=""&gt;switch 语句&lt;/a&gt;：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch (insn)
   {
   case BIN(nop):                  /*nothing */ _bcIndex += len; break;
   // elided
   case BIN(getlocal):             push(getlocal(getOperand(1)/*idx*/, getOperand(2)/*level*/)); _bcIndex += len; break;
   // elided
   case BIN(leave):                _bcIndex = genReturn(pop()); break;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于每个 YARV 字节码，我们将在抽象操作中再现执行时发生的操作。例如，YARV 的操作码 getlocal 把局部区域的值压到堆栈上，因此，这个抽象版生成的代码将从局部区域加载一个值，然后将其压到抽象的堆栈上。其他操作数将消耗此抽象堆栈上的值，比如该例中的 leave。&lt;/p&gt;

&lt;p&gt;最后，我们得到了树！让我们看看上面 foo 示例中 getlocal 和 opt_plus 操作得到的树。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n23n      treetop                                                                    
n22n        lloadi  a[#612  a -24]                             
n21n          aloadi  ep[#599  ep +48]                        
n20n            aloadi  cfp[#600  cfp +48]                       
n19n              aload  &amp;lt;parm 0 Lrb_thread_t;&amp;gt;[#598  Parm]
n28n      treetop                                                                    
n27n        lloadi  b[#613  b -16]                               
n26n          aloadi  ep[#599  ep +48]                        
n25n            aloadi  cfp[#600  cfp +48]                 
n24n              aload  &amp;lt;parm 0 Lrb_thread_t;&amp;gt;[#598  Parm]  
n35n      astorei  pc[#603  pc]                                
n34n        aloadi  cfp[#600  cfp +48]                          
n33n          aload  &amp;lt;parm 0 Lrb_thread_t;&amp;gt;[#598  Parm]       
n32n        aconst 0x5606fbdad740                                                    
n36n      treetop                                                                    
n31n        lcall  vm_opt_plus[#290  helper Method]           
n30n          aload  &amp;lt;parm 0 Lrb_thread_t;&amp;gt;[#598  Parm]       
n29n          aconst 0x5606fbdad7a0                                                  
n22n          ==&amp;gt;lloadi
n27n          ==&amp;gt;lloadi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;为了讲清楚，我将去除一些标志和节点元数据来简化。你可以通过使用 traceFull,log=LOGFILENAME 生成 log 来查看完整输出。&lt;/p&gt;

&lt;p&gt;纵使被简化内容也不少！&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;左边的那一列是节点号，用于标识节点，使得我们可以明确的讨论特定的节点。&lt;/li&gt;
&lt;li&gt; n23n 是 treetop 节点。它用于挂接子节点并保证顺序。这里指的是相对顺序，节点 23 下面的节点一定是在节点 28 下面的节点前被执行的。&lt;/li&gt;
&lt;li&gt;以 n22n 为根的树，是加载传递给 foo 的参数。该树的形状由 Ruby 代码决定。顺序基本上是 C 中的 thread-&amp;gt;cfp-&amp;gt;ep[indexOf(a)] &lt;/li&gt;
&lt;li&gt;n35n 为根的树是存储 YARV 程序计数器。该树的存在是为了确保在 Ruby JIT 中解释器可以随时接管，只要 JIT 代码可能失控就恢复所有的解释器状态（比如，在回调期间发生了异常）。&lt;/li&gt;
&lt;li&gt;n31n 为根的树对应于一个 YARV 指令 opt_plus 的 helper 调用。这是一个生成的回调。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="回调生成"&gt;回调生成&lt;/h3&gt;
&lt;p&gt;前面说过，我会讨论&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/jit.h#L29" rel="nofollow" target="_blank" title=""&gt;jit_callback_struct&lt;/a&gt;更多的细节。它的基本形式，看起来就像这样：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct jit_callbacks_struct {
   /* Include generated callbacks. */
   #include "vm_jit_callbacks.inc" 
   /* ... */
   const char *         (*rb_id2name_f)                 (ID id);
  // ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;之所以用#include 是因为，我们的回调的大部分实际上是在构建期间被生成的，而非手工创建。我们能这样做是得益于 YARV 的聪明设计。&lt;/p&gt;

&lt;p&gt;YARV 使用名为&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/insns.def" rel="nofollow" target="_blank" title=""&gt;insns.def&lt;/a&gt;的“指令定义文件”，用于生成核心解释器循环。但是，我们也可以利用该定义文件自动创建回调。在我们修改的 RubyVM 构建过程中，我们使用相同的处理代码创建解释器循环，并自动发出回调和函数指针声明。&lt;/p&gt;

&lt;p&gt;所以，一个指令定义看起来像&lt;a href="https://github.com/rubyomr-preview/ruby/blob/ad3b419cf7cb56e60195d81a7f411359aeb0484d/insns.def#L380" rel="nofollow" target="_blank" title=""&gt;这篇博客&lt;/a&gt;定义的这样：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
  @c put
  @e to_str
  @j to_str の結果をスタックにプッシュする。
 */
DEFINE_INSN
tostring
()              /* Instruction operands -- these are in the instruction seqeuence */ 
(VALUE val)     /* Values popped from the operand stack                           */ 
(VALUE val)     /* Return value                                                   */ 
{
    val = rb_obj_as_string(val);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们生成的回调（至于 vm_jit.inc）看起来像这样：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VALUE
vm_tostring_jit(VALUE val)
{
    val = rb_obj_as_string(val);
    return val;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;生成回调允许我们支持大量的 Ruby 操作码，而不必手工编写大量的 ILGen 代码。但是有一个权衡：就像 Evan Phoenix 在他 2015 年主题演讲 RubyKaigi 中提到的，这种风格的 JIT 有优化限制，然而，它非常符合我们的 Ruby JIT 哲学。&lt;/p&gt;
&lt;h3 id="代码生成"&gt;代码生成&lt;/h3&gt;
&lt;p&gt;本文不会涉及太多代码生成。因为它并非是 Ruby 特定的，而且也会牵扯其他方面。但是编译的最终产品是一个 startPC，它对应于为方法生成代码的开始。它将会在 vm_exec_jitted 被调用，如上所述。&lt;/p&gt;
&lt;h3 id="总结"&gt;总结&lt;/h3&gt;
&lt;p&gt;啧啧啧——你竟然看完了！非常感谢阅读！本文是对 Ruby+OMR JIT 不太简短的总结。现在，它只适用于 Ruby2.1.5，然而，我们将逐步支持到 Ruby2.4。&lt;/p&gt;

&lt;p&gt;这里是一份仍然需要为 Ruby JIT 构建的任务列表：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;运行时假设：能够推测性的假设和虚拟机状态有关的某些事情，并可以在虚拟机状态改变的时候更新代码。比如假设 + 操作没有被重新定义，但是当它被重新定义的时候能够丢弃编译的方法，或者为编译代码打补丁。&lt;/li&gt;
&lt;li&gt;异步编译：目前，当方法被编译的时候，它会阻止线程执行 Ruby 代码，直到编译完成。这其实是可以避免的，但是为了简单起见，我们选择了不实现异步编译。然而，如果我们实现了异步编译，就可以增加多个编译线程。&lt;/li&gt;
&lt;li&gt;更高级的优化：目前，Ruby JIT 使用的&lt;a href="https://github.com/rubyomr-preview/rbjitglue/blob/eb802a5/ruby/optimizer/Optimizer.cpp#L59" rel="nofollow" target="_blank" title=""&gt;优化列表比较少&lt;/a&gt;。OMR 支持更多优化，我们需要启用它们。&lt;/li&gt;
&lt;li&gt;重新编译：我们有初步的重新编译支持。然而我们用了相同的编译策略，我们需要启用更多的优化。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;我很想听听你对我们迄今为止进展的看法。请在本（原）文下面发表评论，通过&lt;a href="https://dev.eclipse.org/mailman/listinfo/omr-dev" rel="nofollow" target="_blank" title=""&gt;邮件列表&lt;/a&gt;发送一条见解，或者在 GitHub 上提交一个&lt;a href="https://github.com/rubyomr-preview/ruby/issues" rel="nofollow" target="_blank" title=""&gt;issue&lt;/a&gt;。&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 02 Dec 2016 13:02:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/31764</link>
      <guid>https://ruby-china.org/topics/31764</guid>
    </item>
    <item>
      <title>《Ruby 源码�剖析》现已上市！</title>
      <description>&lt;p&gt;&lt;a href="https://book.douban.com/subject/26920403/" rel="nofollow" target="_blank" title=""&gt;豆瓣页面&lt;/a&gt;已创建&lt;/p&gt;

&lt;p&gt;&lt;a href="https://detail.tmall.com/item.htm?id=542465914868&amp;amp;_u=sjt3nvg0374" rel="nofollow" target="_blank" title=""&gt;天猫购买链接&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://product.dangdang.com/24145092.html" rel="nofollow" target="_blank" title=""&gt;当当预售地址&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://item.jd.com/12073396.html" rel="nofollow" target="_blank" title=""&gt;京东预售地址&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://down.51cto.com/data/2269001" rel="nofollow" target="_blank" title=""&gt;前 50 页电子版样章已出&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;汗，我是看到这个帖子「&lt;a href="https://ruby-china.org/topics/31721" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/31721&lt;/a&gt;」 ，才知道我翻译的《Ruby under a Microscope》中文版《Ruby 原理剖析》（标题一激动写错了）现在已经上市了。&lt;/p&gt;

&lt;p&gt;这本书从 2015 年 4 月开始翻译，历经翻译——审核——修订——编辑一审——修订——编辑二审——修订——编辑三审——修订——终审——修订——印刷，现在终于上市了。在翻译期间有不少人追着我问这本书什么时候上市，那么现在大家终于可以入手了：&lt;a href="https://detail.tmall.com/item.htm?id=542465914868&amp;amp;_u=sjt3nvg0374" rel="nofollow" target="_blank" title=""&gt;天猫购买链接&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;京东或当当应该还没有铺开，马上就会有货了！另外电子书可能会在后面发布，不过这个得看出版社的决定了。&lt;/p&gt;

&lt;p&gt;这本书是我的首部译作，我几尽全力的想把它译的足够完美，起码让自己满意，但是到最后，还是留了点小小的遗憾。在终审的时候，有一两处翻译错误以及一些语句的措辞，没有及时改正就已经下印了，虽然可以重印和后面的电子版更正，但是这对我来说还是有点小小的遗憾。希望大家在看的过程中，发现有错误，及时的反馈，反馈到本帖评论中，或者&lt;a href="https://github.com/Ruby-Study/Discuss_Ruby_under_a_microscope" rel="nofollow" target="_blank" title=""&gt;Github 地址&lt;/a&gt;的 issues 中。&lt;/p&gt;

&lt;p&gt;也借着这个地方，给上述的错漏之地加一个说明：
&lt;img src="https://l.ruby-china.com/photo/2016/bc824a754472121264a27e8b5cc16fec.png!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/af9065e790ed805eba11e558ffc13dc7.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这两个地方是我不知道编辑有没有修复，所以贴在这里，大家阅读的时候注意。&lt;/p&gt;

&lt;p&gt;最后，祝大家阅读愉快！&lt;/p&gt;

&lt;p&gt;来自原作者的祝贺：&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/f67dcb308ac771e3d621492185e37ba4.png!large" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;Ruby 源码剖析交流 qq 群 219421893&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Mon, 28 Nov 2016 21:45:18 +0800</pubDate>
      <link>https://ruby-china.org/topics/31724</link>
      <guid>https://ruby-china.org/topics/31724</guid>
    </item>
    <item>
      <title>深思：Ruby 中为什么不能显式的调用私有方法</title>
      <description>&lt;p&gt;原文首发在知乎专栏：&lt;a href="https://zhuanlan.zhihu.com/p/23684649" rel="nofollow" target="_blank"&gt;https://zhuanlan.zhihu.com/p/23684649&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;顺便招人：&lt;a href="https://ruby-china.org/topics/31264" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/31264&lt;/a&gt;&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Tue, 15 Nov 2016 18:21:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/31605</link>
      <guid>https://ruby-china.org/topics/31605</guid>
    </item>
    <item>
      <title>[深圳] 扑象文化招聘 Ruby 工程师 (8k-30K)</title>
      <description>&lt;h2 id="我们是谁"&gt;我们是谁&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;深圳扑象文化传播公司&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;我们不烧钱，也不赚快钱，只想踏踏实实把事情做好；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;我们做到了自负盈亏，自给自足；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;我们一直是同行们抄袭的对象，坚持原创和创新是我们不断前进的动力；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;我们在印刷这个传统且看起来貌似一点也不 Geek 的行业里，却做着 Geek 的事：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在去年短短一年时间里打造了专业摄影师领域里口碑第一的品牌「纸悦」&lt;/li&gt;
&lt;li&gt;开放了生产平台的 API，助力于输出印刷品的合作伙伴&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="产品品牌"&gt;产品品牌&lt;/h2&gt;
&lt;p&gt;「现有品牌」&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;小象 puffant.com，面向大众消费者的个性定制印刷品服务商&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;纸悦 merrypapery.com，国内首家专为婚礼婚纱摄影师提供产品和服务的专业品牌&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;「未来发展」&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;面向品质生活的垂直电商。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;面向生态的开放平台。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="招聘职位"&gt;招聘职位&lt;/h2&gt;&lt;h3 id="Ruby高级工程师（15k - 30k）（1位）"&gt;Ruby 高级工程师（15k - 30k）（1 位）&lt;/h3&gt;
&lt;p&gt;「职位描述」&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;制定团队技术演进方案；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;带领团负责产品开发；&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;设计和开发公司核心功能与技术难点攻关；&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;「任职要求」&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;五年及以上 Web 开发经验，三年以上 Rails 商业项目开发经验&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;精通 Ruby，熟练掌握 Ruby 相关生态系统，精通 Web 开发&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;对 Mysql、Memcached 和 Redis 有深入的应用及优化经验&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;有一定的系统架构能力，对微服务有一定认识&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;优秀的学习能力和解决问题的能力，追求有品质的代码&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;对敏捷开发有丰富的经验和比较深入的认识&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;有责任心，有技术团队管理经验，能够带领团队高效的交付产品&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;可以流畅阅读英文文档；能对技术保持热情&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="Ruby开发工程师（8k - 15k）（2位 - 已招满）"&gt;Ruby 开发工程师（8k - 15k）（2 位 - 已招满）&lt;/h3&gt;
&lt;p&gt;「职位描述」&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;参与产品的需求分析、评审和迭代&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;日常产品功能开发与维护&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;「任职要求」&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;1-3 年的 Rails 商业项目开发经验&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟练使用 Ruby，对 Ruby 的对象模型有基本的了解&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟悉 Javascript/HTML/CSS，了解前端生态系统，有基本的前端开发能力&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;熟练使用 Mysql、Memcached 以及 Redis&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;可以使用 Rspec 或 MiniTest 进行 BDD 开发&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;迎难而上的态度，有责任心以及良好的团队精神&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;优秀的学习能力、领悟能力和沟通能力&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;可以流畅阅读英文文档&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;全日制 985、211 大学本科及以上学历计算机专业优先考虑&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="基本福利待遇"&gt;基本福利待遇&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;国家规定的一样不会少&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;入职即配 Mac 设备，全局科学上网&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;正常的双休及节假日，不加班，我们不是压榨工厂&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;不定期的团队聚餐以及团建活动，在深圳这个偌大的城市我们一起奋斗&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;勤奋的你也少不了考勤奖&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;如果是程序媛会有生理假&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="联系方式："&gt;联系方式：&lt;/h2&gt;
&lt;p&gt;汉东（首席技术顾问）：handong@puffant.com&lt;/p&gt;

&lt;p&gt;应聘的小伙伴注意：面试前会有一份实战小测试希望可以认真完成。&lt;/p&gt;
&lt;h2 id="工作环境及团建活动照片"&gt;工作环境及团建活动照片&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2016/ec26675b1407f0a5d4ba1237bae3e413.jpg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/6c2b97409b985be6ae7117c11f334572.jpg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/40e3c9d32100cea0a448422ce5cce971.jpg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/3d40385ff7c3d00385159bd79599f557.jpg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/cdea8fa7b866b2539d84e83ee6467e15.jpg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/b6a5563c5caff708e1cd145f134f853b.jpg!large" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2016/8ab139b317253c1300d8b328272dab92.png!large" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Sun, 09 Oct 2016 16:09:53 +0800</pubDate>
      <link>https://ruby-china.org/topics/31264</link>
      <guid>https://ruby-china.org/topics/31264</guid>
    </item>
    <item>
      <title>[深圳] 扑象文化招聘 Ruby 工程师 [10 - 20K]</title>
      <description>&lt;h2 id="我们是谁？"&gt;我们是谁？&lt;/h2&gt;
&lt;p&gt;深圳扑象文化传播公司，我司旗下产品：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;小象 puffant.com，面向大众消费者的个性定制印刷品服务商&lt;/li&gt;
&lt;li&gt;纸悦 merrypapery.com，国内首家专为婚礼婚纱摄影师提供产品和服务的专业品牌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们不烧钱，也不赚快钱，只想踏踏实实把事情做好；&lt;/p&gt;

&lt;p&gt;我们做到了自负盈亏，自给自足；&lt;/p&gt;

&lt;p&gt;我们一直是同行们抄袭的对象，坚持原创和创新是我们不断前进的动力；&lt;/p&gt;

&lt;p&gt;我们在印刷这个传统且看起来貌似一点也不 Geek 的行业里，却做着 Geek 的事：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在去年短短一年时间里打造了专业摄影师领域里口碑第一的品牌「纸悦」&lt;/li&gt;
&lt;li&gt;开放了生产平台的 API，助力于输出印刷品的合作伙伴&lt;/li&gt;
&lt;li&gt;在未来，我们会像更多的个人开发者开放我们的接口，让打印无处不在&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这次招聘除了为了支撑原有的业务，我们也计划在新的一年开拓新的业务线，包括移动和硬件，我们在路上。&lt;/p&gt;
&lt;h2 id="Ruby 高级工程师"&gt;Ruby 高级工程师&lt;/h2&gt;&lt;h2 id="基本要求"&gt;基本要求&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;扎实的 Ruby 语言功底&lt;/li&gt;
&lt;li&gt;两年以上 Ruby on Rails 实际项目经验，有过 API 开发经验更好&lt;/li&gt;
&lt;li&gt;熟悉 Web 前端开发（HTML/CSS/Javascript），了解一些前端框架，比如 React.js 更好&lt;/li&gt;
&lt;li&gt;熟悉 Mysql，了解基本的优化常识&lt;/li&gt;
&lt;li&gt;熟悉 Git/Github&lt;/li&gt;
&lt;li&gt;具备良好的编码习惯和逻辑条理性，对复杂业务逻辑能快速理解并转化为技术需求&lt;/li&gt;
&lt;li&gt;具备学习能力，良好的团队意识和协作精神，有较强的沟通能力&lt;/li&gt;
&lt;li&gt;有编写自动化测试用例的习惯&lt;/li&gt;
&lt;li&gt;具备流畅阅读英文文档的能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="加分项"&gt;加分项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有 Java，PHP, Python 等其他语言开发经验&lt;/li&gt;
&lt;li&gt;了解敏捷开发流程（Scrum）&lt;/li&gt;
&lt;li&gt;热爱服务端开发，对后台服务的整体架构设计有成功经验&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="为什么你要加入我们"&gt;为什么你要加入我们&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;成长 -- 我们鼓励你能持续的学习，尝试不同的方法解决问题&lt;/li&gt;
&lt;li&gt;自由 -- 不打卡，弹性工作制&lt;/li&gt;
&lt;li&gt;影响力 -- 我们公司不大，你做的事都很重要&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;福利待遇：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;月薪 10 - 20K&lt;/li&gt;
&lt;li&gt;国家规定要求有的一样也不会少&lt;/li&gt;
&lt;li&gt;入职即配 Mac 设备，全局翻墙&lt;/li&gt;
&lt;li&gt;双休以及正常的节假日，我们不是劳动力压榨工厂&lt;/li&gt;
&lt;li&gt;不定期的团队聚餐以及团建活动，在深圳这个偌大的城市里我们一起奋斗&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="一些有关你的信息"&gt;一些有关你的信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;我们喜欢乐观、自信、开朗的你，&lt;/li&gt;
&lt;li&gt;我们喜欢主动、积极、活跃的你，&lt;/li&gt;
&lt;li&gt;如果你是 Github 的活跃用户最好不过，&lt;/li&gt;
&lt;li&gt;不管你做的是小工具还是 side project，&lt;/li&gt;
&lt;li&gt;我们更愿意看到你的 Github Contributions 是一片绿油油，&lt;/li&gt;
&lt;li&gt;认可工程师文化以及工程师价值，对自己的工作充满热情。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;为了对你有初步的认识，希望你能回答一些问题（附在简历中或邮件正文即可）：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;你有 Github, Twitter, 个人博客吗？&lt;/li&gt;
&lt;li&gt;你最喜欢哪些技术书籍？&lt;/li&gt;
&lt;li&gt;你实现过最复杂的程序？&lt;/li&gt;
&lt;li&gt;你解决过的最困难的问题？&lt;/li&gt;
&lt;li&gt;除了编程，你还喜欢什么？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="联系方式"&gt;联系方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;handong@puffant.com&lt;/li&gt;
&lt;li&gt;liuj@puffant.com&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 12 Aug 2016 15:52:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/30810</link>
      <guid>https://ruby-china.org/topics/30810</guid>
    </item>
    <item>
      <title>[深圳] 扑象文化招聘 Ruby 工程师</title>
      <description>&lt;h2 id="我们是谁？"&gt;我们是谁？&lt;/h2&gt;
&lt;p&gt;深圳扑象文化传播公司，我司旗下产品：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;小象 puffant.com，面向大众消费者的个性定制印刷品服务商&lt;/li&gt;
&lt;li&gt;纸悦 merrypapery.com，国内首家专为婚礼婚纱摄影师提供产品和服务的专业品牌&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们不烧钱，也不赚快钱，只想踏踏实实把事情做好；&lt;/p&gt;

&lt;p&gt;我们做到了自负盈亏，自给自足；&lt;/p&gt;

&lt;p&gt;我们一直是同行们抄袭的对象，坚持原创和创新是我们不断前进的动力；&lt;/p&gt;

&lt;p&gt;我们在印刷这个传统且看起来貌似一点也不 Geek 的行业里，却做着 Geek 的事：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;在去年短短一年时间里打造了专业摄影师领域里口碑第一的品牌「纸悦」&lt;/li&gt;
&lt;li&gt;开放了生产平台的 API，助力于输出印刷品的合作伙伴&lt;/li&gt;
&lt;li&gt;在未来，我们会像更多的个人开发者开放我们的接口，让打印无处不在&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这次招聘除了为了支撑原有的业务，我们也计划在新的一年开拓新的业务线，包括移动和硬件，我们在路上。&lt;/p&gt;
&lt;h2 id="Ruby 高级工程师"&gt;Ruby 高级工程师&lt;/h2&gt;&lt;h2 id="基本要求"&gt;基本要求&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;扎实的 Ruby 语言功底&lt;/li&gt;
&lt;li&gt;两年以上 Ruby on Rails 实际项目经验，有过 API 开发经验更好&lt;/li&gt;
&lt;li&gt;熟悉 Web 前端开发（HTML/CSS/Javascript），了解一些前端框架，比如 React.js 更好&lt;/li&gt;
&lt;li&gt;熟悉 Mysql，了解基本的优化常识&lt;/li&gt;
&lt;li&gt;熟悉 Git/Github&lt;/li&gt;
&lt;li&gt;具备良好的编码习惯和逻辑条理性，对复杂业务逻辑能快速理解并转化为技术需求&lt;/li&gt;
&lt;li&gt;具备学习能力，良好的团队意识和协作精神，有较强的沟通能力&lt;/li&gt;
&lt;li&gt;有编写自动化测试用例的习惯&lt;/li&gt;
&lt;li&gt;具备流畅阅读英文文档的能力&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="加分项"&gt;加分项&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;有 Java，PHP, Python 等其他语言开发经验&lt;/li&gt;
&lt;li&gt;了解敏捷开发流程（Scrum）&lt;/li&gt;
&lt;li&gt;热爱服务端开发，对后台服务的整体架构设计有成功经验&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="为什么你要加入我们"&gt;为什么你要加入我们&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;成长 -- 我们鼓励你能持续的学习，尝试不同的方法解决问题&lt;/li&gt;
&lt;li&gt;自由 -- 不打卡，弹性工作制&lt;/li&gt;
&lt;li&gt;影响力 -- 我们公司不大，你做的事都很重要&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;福利待遇：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;月薪 10 - 18K&lt;/li&gt;
&lt;li&gt;国家规定要求有的一样也不会少&lt;/li&gt;
&lt;li&gt;入职即配 Mac 设备，全局翻墙&lt;/li&gt;
&lt;li&gt;双休以及正常的节假日，我们不是劳动力压榨工厂&lt;/li&gt;
&lt;li&gt;不定期的团队聚餐以及团建活动，在深圳这个偌大的城市里我们一起奋斗&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="一些有关你的信息"&gt;一些有关你的信息&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;我们喜欢乐观、自信、开朗的你，&lt;/li&gt;
&lt;li&gt;我们喜欢主动、积极、活跃的你，&lt;/li&gt;
&lt;li&gt;如果你是 Github 的活跃用户最好不过，&lt;/li&gt;
&lt;li&gt;不管你做的是小工具还是 side project，&lt;/li&gt;
&lt;li&gt;我们更愿意看到你的 Github Contributions 是一片绿油油，&lt;/li&gt;
&lt;li&gt;认可工程师文化以及工程师价值，对自己的工作充满热情。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;为了对你有初步的认识，希望你能回答一些问题（附在邮件正文即可）：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;你有 Github, Twitter, 个人博客吗？&lt;/li&gt;
&lt;li&gt;你最喜欢哪些技术书籍？&lt;/li&gt;
&lt;li&gt;你实现过最复杂的程序？&lt;/li&gt;
&lt;li&gt;你解决过的最困难的问题？&lt;/li&gt;
&lt;li&gt;除了编程，你还喜欢什么？&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="联系方式"&gt;联系方式&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;handong@puffant.com&lt;/li&gt;
&lt;li&gt;liuj@puffant.com&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 24 Jun 2016 16:52:08 +0800</pubDate>
      <link>https://ruby-china.org/topics/30362</link>
      <guid>https://ruby-china.org/topics/30362</guid>
    </item>
    <item>
      <title>[已解决] 请停止对「Ruby under a Microscope」一书的侵权</title>
      <description>&lt;p&gt;昨天 QQ 群看到有人分享一篇文章：&lt;/p&gt;

&lt;p&gt;&lt;a href="http://mp.weixin.qq.com/s?__biz=MzA3NjUyMjIyMQ==&amp;amp;mid=208775671&amp;amp;idx=1&amp;amp;sn=cdf38d9786cc7e3dca0c7600388196c0&amp;amp;scene=5#rd" rel="nofollow" target="_blank"&gt;http://mp.weixin.qq.com/s?__biz=MzA3NjUyMjIyMQ==&amp;amp;mid=208775671&amp;amp;idx=1&amp;amp;sn=cdf38d9786cc7e3dca0c7600388196c0&amp;amp;scene=5#rd&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="我进去一看，完全是对「Ruby under a Microscope」第五章的抄袭。"&gt;我进去一看，完全是对「Ruby under a Microscope」第五章的抄袭。&lt;/h3&gt;&lt;h3 id="目前这本书已经由华中科技出版社引入版权，由我翻译并进入了最后的审校阶段，@user1 ，你们自己看了书，写出自己的原创内容无所谓，但是目前的这种纯非法翻译行为，已经构成对本书的侵权，请马上停止这种无耻的行为。"&gt;目前这本书已经由华中科技出版社引入版权，由我翻译并进入了最后的审校阶段，&lt;a href="/michael_roshen" class="user-mention" title="@michael_roshen"&gt;&lt;i&gt;@&lt;/i&gt;michael_roshen&lt;/a&gt; ，你们自己看了书，写出自己的原创内容无所谓，但是目前的这种纯非法翻译行为，已经构成对本书的侵权，请马上停止这种无耻的行为。&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;截图：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://l.ruby-china.com/photo/2015/86d254488b7cadde3e7c58c30ae534f6.png" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2015/64c3dfb1b6305d3368c13bbe30d809b6.png" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2015/c9317816804808667596c8c61f2a1d88.png" title="" alt=""&gt;
&lt;img src="https://l.ruby-china.com/photo/2015/23ed2319bb671eb1bac6352b34524235.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;————————————&lt;/p&gt;

&lt;p&gt;P.S  已解决。希望大家可以努力维护原创内容。 &lt;a href="https://ruby-china.org/topics/26822" rel="nofollow" target="_blank"&gt;https://ruby-china.org/topics/26822&lt;/a&gt;&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 07 Aug 2015 17:25:49 +0800</pubDate>
      <link>https://ruby-china.org/topics/26817</link>
      <guid>https://ruby-china.org/topics/26817</guid>
    </item>
    <item>
      <title>[广州] 艾威 (AVTECH) 招 Ruby 技术顾问「１名」「帮朋友代招」</title>
      <description>&lt;p&gt;帮朋友代招一个技术顾问，在广州，职责是带着客户的开发人员做一个项目。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;具体的技术要求如下：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Skill set:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;backbone&lt;/li&gt;
&lt;li&gt;backbone.marionette.&lt;/li&gt;
&lt;li&gt;coffeescript&lt;/li&gt;
&lt;li&gt;jasmine&lt;/li&gt;
&lt;li&gt;rails-api&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;至少 1 年半以上工作经验，最少完成一个以上的中大型项目，最好能提供完整的案例，要了解主流的 GEM 包的使用。较强的解决疑难问题的能力。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;联系方式：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;联系人：朱大滨
联系电话：13901626342
联系 QQ: 2355540680
联系 Email: dabinzhu@avtechcn.cn&lt;/p&gt;

&lt;p&gt;直接联系我也可以：
QQ 247026628&lt;/p&gt;

&lt;p&gt;不招远程，必须是可以到现场的，具体待遇面谈。&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Thu, 31 Jul 2014 10:18:26 +0800</pubDate>
      <link>https://ruby-china.org/topics/20767</link>
      <guid>https://ruby-china.org/topics/20767</guid>
    </item>
    <item>
      <title>[北京]「点名时间」招 Ruby 开发工程师 / Web 前端开发工程师「本期招聘结束」</title>
      <description>&lt;h2 id="公司介绍："&gt;&lt;strong&gt;公司介绍：&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;是时候了。
中国需要你。&lt;/p&gt;

&lt;p&gt;点名时间，国内最大的众筹网站： &lt;a href="http://www.demohour.com" rel="nofollow" target="_blank" title=""&gt;www.demohour.com&lt;/a&gt; ，期待你的加入。在这个处于创新变革时期的中国，点名时间，就是支持创新的新力量。我们需要你，来一起见证中国创新明星团队的诞生。&lt;/p&gt;

&lt;p&gt;我们团队已经拿到经纬、英特尔 A 轮数百万美元投资（见 36kr 报道：&lt;a href="http://www.36kr.com/p/208838.html" rel="nofollow" target="_blank"&gt;http://www.36kr.com/p/208838.html&lt;/a&gt;），我们的团队即将大展拳脚，同时，你的加入，也是一个机会，不是吗？&lt;/p&gt;

&lt;p&gt;公司地址：北京广渠路竞园图片产业基地 52D，可以看高德地图，查：竞园 SPR coffee，就在这个咖啡馆同一排。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;基本待遇：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; 五险一金&lt;/li&gt;
&lt;li&gt; 每日餐补（20 元）&lt;/li&gt;
&lt;li&gt; 每月工作奖金（非绩效考核，公司每人都有）&lt;/li&gt;
&lt;li&gt; 不打卡，弹性工作制 (10 点 - 19 点)&lt;/li&gt;
&lt;li&gt; 年底双薪&lt;/li&gt;
&lt;li&gt; 很 nice 的同事&lt;/li&gt;
&lt;li&gt; 其他福利正在完善中（期权等）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;友情提示&lt;/strong&gt; ：投递简历尽量客观，填写的「期望薪资」希望可以在我们给定的范围里，即使你很优秀，也是需要在试用期或以后的工作中证明自己的优秀，而不是投简历的时候（公司的每个人都是这样的）。这里没有固定工作一年或几年才涨工资的规定，只要你有一定的贡献，工资随时可以涨。&lt;/p&gt;
&lt;h2 id="招聘职位"&gt;&lt;strong&gt;招聘职位&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Ruby 工程师：&lt;/strong&gt;
&lt;strong&gt;薪资&lt;/strong&gt; : (10 - 20k)&lt;/p&gt;

&lt;p&gt;基本要求：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; 看得懂 Ruby 代码（不要 google），写得出规范的 Ruby 代码（不要 google），对元编程有一定了解，有自己的认识（不要背书），对面向对象思想有一定认识（不要背书），了解 Ruby 相关的基础开发知识和常用工具（gem，bunlder，rvm/rbenv，rspec 等）&lt;/li&gt;
&lt;li&gt; 用 Rails 独立开发过完整的项目（或者是一些完整的功能），对 MVC, RESTful 都有自己的认识，了解 Rails 的工作机制。&lt;/li&gt;
&lt;li&gt; 底层数据库（关系型数据库：Mysql）的知识要充分掌握，知道如何去优化，有一定的经验更好。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;加分项：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; 常去 Github&lt;/li&gt;
&lt;li&gt; 写技术 blog&lt;/li&gt;
&lt;li&gt; 有持续学习的激情（喜欢阅读英文技术文档和书籍）&lt;/li&gt;
&lt;li&gt; 有团队精神&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;说明：暂时不招远程&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;strong&gt;Web 前端开发工程师：&lt;/strong&gt;
&lt;strong&gt;薪资&lt;/strong&gt; : (8 - 16k)&lt;/p&gt;

&lt;p&gt;基本要求：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; HTML、CSS、JavaScript 基础扎实，了解 HTTP 协议以及 Ajax 相关技术原理。&lt;/li&gt;
&lt;li&gt; 熟练掌握 JQuery（或 Zepto），了解 JQuery 工作机制。&lt;/li&gt;
&lt;li&gt; 熟悉 web 开发，有完整的商业项目或产品的实际工作经验，了解各种浏览器之间的差异，处理各种兼容问题。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;加分项：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; 有移动 web 开发经验&lt;/li&gt;
&lt;li&gt; 懂 Ruby、Node.js 更好&lt;/li&gt;
&lt;li&gt; 常去 Github&lt;/li&gt;
&lt;li&gt; 技术 blog&lt;/li&gt;
&lt;li&gt; 持续学习精神（喜欢阅读英文技术文档和书籍）&lt;/li&gt;
&lt;li&gt; 团队精神&lt;/li&gt;
&lt;/ol&gt;

&lt;hr&gt;

&lt;p&gt;&lt;strong&gt;联系 Email：handong@demohour.com&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;也欢迎大家加入我们建立的技术交流 QQ 群：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;【前端交流群】332776771&lt;/p&gt;

&lt;p&gt;【Ruby 交流群】334565026&lt;/p&gt;

&lt;p&gt;关于公司的环境，可以去之前发的招聘贴观看：&lt;a href="http://ruby-china.org/topics/16716" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/16716&lt;/a&gt;&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Wed, 12 Feb 2014 11:53:57 +0800</pubDate>
      <link>https://ruby-china.org/topics/17186</link>
      <guid>https://ruby-china.org/topics/17186</guid>
    </item>
    <item>
      <title>2014 年 全球各地的 Ruby Conf 活动</title>
      <description>&lt;p&gt;感兴趣的，可以去这里查看：&lt;a href="http://rubyconferences.org/" rel="nofollow" target="_blank"&gt;http://rubyconferences.org/&lt;/a&gt;&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Sat, 25 Jan 2014 21:32:24 +0800</pubDate>
      <link>https://ruby-china.org/topics/16997</link>
      <guid>https://ruby-china.org/topics/16997</guid>
    </item>
    <item>
      <title>关于招聘的一些感触</title>
      <description>&lt;p&gt;前几天发过一个招聘贴：&lt;a href="http://ruby-china.org/topics/16716" rel="nofollow" target="_blank"&gt;http://ruby-china.org/topics/16716&lt;/a&gt; &lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;有人对此招聘表示了不满：  「看到对工作时间（工作经验）的限制，就算满足也不会去。这样我想是招不到一流的人」&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;很多用 ruby 的，都是半路出家的。这些人在其它领域用编程语言也有好几年了，但 ruby 在中国的发展时间没那么长，那些转过来的人会有 2 年以上用 ruby 编程的经验？难道他们就没有责任心和团队精神？一些编程能力强的人，用语言也是很快可以上手的，也可以很快了解语言的核心特质的。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;现在大学里面是不教 ruby 的，在现在中国的环境里面，好像也没有特别大的公司用 ruby 吧，会 ruby 大多是自学的，即然是自学，肯定是有内在的动力吧，想必都是想自己做点东西的；里面提到是编运营的，如果不主动找，我想很少人会主动上门吧，有同感的同学请举手...&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;好像类似 facebook 的招聘，我是比较认同的：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;考查些语言的特性和各方面的基础的知识；&lt;/li&gt;
&lt;li&gt;考查算法方面的能力；&lt;/li&gt;
&lt;li&gt;考查系统设计方面的能力。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;等等。。。我就不贴了。&lt;/p&gt;
&lt;h2 id="我不知道这些想法是不是大多数人的想法，总之下面是我的一些感触，也算是解释吧："&gt;&lt;strong&gt;我不知道这些想法是不是大多数人的想法，总之下面是我的一些感触，也算是解释吧：&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;我这边招人本来就不考虑别的语言转型到 Ruby 的，所以会有这样的条件限制，当然站在你求职者的角度上看，是有点门槛太高，但是我作为招聘方，我们这次招聘，是属于组建技术团队期，我们的技术栈就是 Ruby，要求 Ruby 的工作经验有什么问题吗？我们没有时间去等你很快了解语言特质的，所以我们只招符合这条要求的。&lt;/p&gt;

&lt;p&gt;拿第二条来说，综合我刚才说的，刚毕业的大学生肯定也不会去考虑的啦，我们是创业公司，不是大公司，目前招的职位不是一个培养职位，偏运营是指公司的商业性质，并不代表来的就是苦力了，如果你了解我，就该知道我对技术是什么样的情结，我花时间录 Ruby 的视频，完全是这种技术情结在驱动，你以为我赚了多少钱呢？&lt;/p&gt;

&lt;p&gt;当然，面向大学生，以后可能会招一些实习岗位，我们是创业公司，只能看业务的发展，我个人来说，当然希望公司提供若干 Ruby 职位，但是现实情况不允许。&lt;/p&gt;

&lt;p&gt;我也说说我这边面试的情况吧：
第一，我会根据你的简历情况做个简单分析（技术结构，包括 github 源码）
第二，面试的时候没有笔试，只是问你一些 Ruby 的基础问题，比如让你解释下 Ruby 的 block 和闭包，比如问你 Rails 的 rack，数据库方面的一些基础，算法方面我们就没考虑了，因为我们是偏运营的公司，对算法的要求没有那么高。
第三，我会考察一些你的沟通能力，性格，团队精神等因素。&lt;/p&gt;

&lt;p&gt;然后综合评价，再来决定是否录用。&lt;/p&gt;

&lt;p&gt;说实话，来面试的人，有的连 symbol 和 string 啥区别都不知道，薪水开到年薪 20w，这样的人让我怎么录取呢？难道我招你过来，要等两年后 Ruby 基础学好再分配给你工作吗？&lt;/p&gt;

&lt;p&gt;你如果觉得自己有能力，完全可以投简历，给我投简历不满一年工作经验的，我也照样面试过。&lt;/p&gt;

&lt;p&gt;我们是互联网公司，我们这边的人都很好，不加班，不打卡，只要求你完成计划的内容，这也叫苦力？&lt;/p&gt;

&lt;p&gt;当然我知道学 Ruby 的人，都是属于程序员中比较优秀的，这个经验限制只是因为职位的要求，而不是否定你们的潜力。&lt;/p&gt;

&lt;p&gt;本来我没必要解释这么多的，既然看到就说一说吧。如果你觉得自己能力足够，那就用简历来说话吧，其他的也没啥好讨论了。&lt;/p&gt;

&lt;p&gt;P.S，关于技术，我更关注用技术做什么事，Ruby 只是个工具，我们使用这个工具把我们要做的事做到最好。希望更多想做点事的朋友加入我们。&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Mon, 20 Jan 2014 19:38:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/16893</link>
      <guid>https://ruby-china.org/topics/16893</guid>
    </item>
    <item>
      <title>[北京]「点名时间」招 Ruby 开发工程师 / 前端开发工程师 (祝大家新年快乐！)</title>
      <description>&lt;p&gt;是时候了。
中国需要你。&lt;/p&gt;

&lt;p&gt;我们是一群 70 后 80 后和 90 后。
我们来自台北、贵州、江苏、云南、辽宁、和北京。
我们是技术人、设计人、创意人、媒体人和营销人。
我们不想再用劣质品，接受劣质的服务，被劣质的态度对待，
我们不希望中国永远都是山寨的代名词。
我们相信创新能带来巨大的商业价值。&lt;/p&gt;

&lt;p&gt;点名时间： &lt;a href="http://www.demohour.com" rel="nofollow" target="_blank" title=""&gt;www.demohour.com&lt;/a&gt;  ，期待你的加入。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;【Ruby 开发工程师】
要求：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;至少两年 Ruby 开发实际工作经验。（必须）&lt;/li&gt;
&lt;li&gt;Ruby 有一定基础（必须），熟悉 Rails 开发框架，熟悉 Rails 之外的开发框架更好。&lt;/li&gt;
&lt;li&gt;熟悉 Javascript/ CSS（3）/HTML（5）及其相关工具、框架，比如：jQuery，sass/less，bootstrap 等（这也算是 Rails 开发工程师的标配吧） &lt;/li&gt;
&lt;li&gt;熟悉 Mysql/Postgresql 等关系型数据库，熟悉 Memcached，熟悉 NoSql（redis/mongodb）更好。&lt;/li&gt;
&lt;li&gt;熟练使用 Rails 相关部署工具。&lt;/li&gt;
&lt;li&gt;关注 Ruby 社区的技术动向，有良好的学习习惯，有 Geek 倾向。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;「薪资范围」10k - 20k&lt;/p&gt;

&lt;p&gt;【前端开发工程师】
注：此职位偏 CSS 向，CSS 基本功必须过硬
要求：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;至少两年的前端开发工作经验。&lt;/li&gt;
&lt;li&gt;对 PC web 和移动 web 的页面开发标准有一定了解。&lt;/li&gt;
&lt;li&gt;对前端 web 标准有正确的理解，熟悉各种前端开发规范。&lt;/li&gt;
&lt;li&gt;熟悉各大浏览器之间的差异，并可熟练解决各种浏览器兼容问题。&lt;/li&gt;
&lt;li&gt;CSS 基本功必须过硬，javascript 一般就行。&lt;/li&gt;
&lt;li&gt;熟悉前端开发常用工具及框架，比如 jQuery，sass/less，bootstrap。&lt;/li&gt;
&lt;li&gt;对前端技术的开源社区要有充分关注，有良好的学习习惯，有 Geek 倾向。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;「薪资范围」8k - 16k&lt;/p&gt;

&lt;p&gt;其他福利：&lt;/p&gt;

&lt;p&gt;基本的五险一金都有，弹性工作制，无打卡，无加班文化，满一年年底双薪，美女如云。&lt;/p&gt;

&lt;p&gt;至于其他福利，还在完善中。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;公司是偏运营，但是也注重技术，希望各位朋友加入，可以一起交流成长。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;联系 Email：handong@demohour.com&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;也欢迎大家加入我们建立的技术交流 QQ 群：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;【前端交流群】332776771&lt;/p&gt;

&lt;p&gt;【Ruby 交流群】334565026&lt;/p&gt;

&lt;p&gt;工作地点：北京朝阳竞园图片产业基地，广渠路这边，上两张工作环境的图：&lt;/p&gt;

&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/2014/007ed3493366ee28b7feb8e3e39a8466.jpg" title="" alt=""&gt;
&lt;img src="//l.ruby-china.com/photo/2014/217bf523119e3d909a4e2c81d2578da3.jpg" title="" alt=""&gt;
&lt;img src="//l.ruby-china.com/photo/2014/ab7308e22d9d5a10c13f58d33aefd808.jpg" title="" alt=""&gt;
&lt;img src="//l.ruby-china.com/photo/2014/bbb9b4b6f7521dfa3f632c84c9e69318.jpg" title="" alt=""&gt;
&lt;img src="//l.ruby-china.com/photo/2014/7423cc426803d578c33bde55e0a2067e.jpg" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;【此招聘贴长期有效】&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Fri, 10 Jan 2014 12:37:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/16716</link>
      <guid>https://ruby-china.org/topics/16716</guid>
    </item>
    <item>
      <title>「诱人的 Ruby」入门篇课程调查</title>
      <description>&lt;p&gt;借用宝地，发个调查问卷：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;点击&lt;/strong&gt;  :    &lt;a href="http://www.wenjuan.com/s/FVnqma" rel="nofollow" target="_blank"&gt;http://www.wenjuan.com/s/FVnqma&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;一共 7 道调查题，希望 Ruby China 里看过视频的朋友帮忙完成调研，多谢了。&lt;/p&gt;

&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/2013/89bbc6920771a85ca70021c13054b7dd.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;今天把调查报告挂再了课程页面上，参与调查者，在建议里加上自己的 51cto id，就可以获取一定数量学分，学分可以抵金币来用。&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Wed, 04 Dec 2013 14:00:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/15991</link>
      <guid>https://ruby-china.org/topics/15991</guid>
    </item>
    <item>
      <title>「勿忘初心」TDD， Don ‘t DDT</title>
      <description>&lt;p&gt;偶尔翻到自己五年前写的关于 TDD 的文章，又看一遍，感觉当时的自己是走在正确的路上。但是这么多年过去了，BDD 也在流行，自己却没有一直沿着这条路走下去，为什么？老文重拾，感慨良多。&lt;/p&gt;

&lt;p&gt;这个过程是我当时在用 Ruby 改造一个 php 的遗留系统，具体细节已遗忘。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;&lt;strong&gt;正文&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;一直有个疑问，对于遗留系统，我们该如何 TDD？&lt;/p&gt;

&lt;p&gt;我个人比较认同 TDD 是一种设计方法，不能代替真正意义上的测试。是帮助我们设计自己代码的一种方法。对于遗留系统，面对一堆需求文档，面对一陀陀已经难 以继续维护的陈旧代码，你的心是否哇凉哇凉的？做为一个使用 Rails 的开发人员，难道你要把这些代码翻译为 Ruby 代码吗？
答案当然是不！
很多时候，我们虽然很清楚要 TDD，但是很多时候我们是在 DDT。基本上是根据遗留系统的代码把功能代码写的差不多了，才想起来写测试。写完之后，用流行的 rcov 测试一下测试代码覆盖率，不足的地方再加上测试？回头想想，我们引入 TDD 的初衷是这样的吗？大家都心知肚明，并不是这样的！
重新思考 TDD 之后，我决定在现做的这个 ticket 里完全采用了 TDD 的方式去开发，今天一天下来，感触颇深：
1。昨天拿到 php 源码，一看代码，了不得啊，和我功能相关的源码文件之有三个，但代码却有三千多行。我该怎么办？我肯定不可能把那三千多行都看完吧。我该如何 TDD？
     T 代表 Test，测试驱动开发，很显然，是先有测试，要不谈何驱动开发。但是没有功能代码，你测试什么呀？既然 TDD 是一种设计方法，那么这个测试，代表的应该是你大脑中对这个功能的自我认知。如果对需求了解不清楚，你是没有办法对这个功能产生自我的认知的。硬着头皮整理了一下需求文档，在脑中形成一个大概的轮廓之后，就可以动手写测试了。此功 能是要生成一个报表，就是一个 create -&amp;gt; show 的过程。一般人想到的先是页面，我是一般人，所以我也是从页面开始的，根据已经明确的需求写下自己对这个页面的幻想：&lt;/p&gt;

&lt;p&gt;/spec/views/reports/new.html.erb_spec.rb中：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'/../../spec_helper'&lt;/span&gt;

&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"reports/new.html.erb"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="nf"&gt;.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"should render new.html.erb"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s2"&gt;"/reports/new.html.erb"&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;should&lt;/span&gt; &lt;span class="n"&gt;have_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form[action=/reports/new]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

       &lt;span class="c1"&gt;#应该有一个label来表明这个field是company name&lt;/span&gt;
          &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"company name:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                       
          &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select#data_company_id[name=?]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"data[company_id]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         

     &lt;span class="c1"&gt;#应该有个下拉列表来让用户选择存在的company name&lt;/span&gt;
          &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Report Filter by Year:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                     

     &lt;span class="c1"&gt;#应该有个时间列表来让用户选择生成报表数据的时间段。&lt;/span&gt;
         &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select#report_filter_by_year[name=?]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"report_filter[by_year]"&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="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

  &lt;span class="nf"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;好了，写到这，我脑中只剩下了一点不清楚的需求。也就是说，我如果能把这个测试写完，脑中对这部分的需求应该就明朗了。继续看文档，看 php 代码，只看一 些 sql 语句。一个疑问就是这个页面用不用加一个排序的下拉列表？这个疑问得问和我们合作的老外 Andy，正好他还未到睡觉时间，就问他：
       new page whether should need  select down list to  sort by  some  column ?  他回答：sounds  like good .
  very good ,   我可以把上面这句英语翻译成 rspec 代码：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Sort by:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select#sort_by_sorted_on[name=?]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"sort_by[sorted_on]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样我的这个测试就全部写完了：如下&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt; &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dirname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kp"&gt;__FILE__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;'/../../spec_helper'&lt;/span&gt;

&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s2"&gt;"reports/new.html.erb"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;

    &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  &lt;span class="nf"&gt;.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

    &lt;span class="nf"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"should render new.html.erb"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="s2"&gt;"/reports/new.html.erb"&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;should&lt;/span&gt; &lt;span class="n"&gt;have_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"form[action=/reports/new]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
         &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"company name:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                       
         &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select#data_company_id[name=?]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"data[company_id]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         
         &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Report Filter by Year:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                                     
          &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select#report_filter_by_year[name=?]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"report_filter[by_year]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

         &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'label'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"Sort by:"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;with_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'select#sort_by_sorted_on[name=?]'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s2"&gt;"sort_by[sorted_on]"&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="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nf"&gt;.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

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

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开 autotest，运行，报错：没有这个页面。好办啊，建个页面不就得了。建立 new.html.erb.
    运行测试，报错，没有  company name: , 好办啊，在 new.html.erb 里加个 label 不就得了。
    根据错误信息的提示，我很快就把页面的基本元素写好了。
    但是下拉列表的选项，是需要从数据库里查询来生成 options 的。那么就在 model 里写个测试方法了：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#应该返回一个以年份组成的二维数组&lt;/span&gt;
&lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"should return a array by year"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;   
     &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_filter_year&lt;/span&gt;
     &lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_an_instance_of&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="n"&gt;year&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="nf"&gt;should&lt;/span&gt; &lt;span class="n"&gt;be_an_instance_of&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="k"&gt;end&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样，运行 autotest，会报错，Entry 没有定义 get_filter_year 方法，好办啊，加上不就得了吗。
      。。。    。。。
      不断的根据错误提示来写功能代码。
     。。。。
      测试终于全部通过。
      我的功能代码也完成了。
      我对页面的那点幻想终于成了现实。
      这就是 TDD。&lt;/p&gt;

&lt;p&gt;这个 TDD 的过程里，我没有开过浏览器。一点不吹牛，信不信由你！&lt;/p&gt;

&lt;p&gt;TDD 的好处：
      1。帮助你理清思维，去把遗留系统的需求逐步的挖掘出来，而不用去把客户给的三千行代码看完。
      2。驱动你的开发。整理需求写完测试之后，然后只需要运行 autotest 来利用 failure 信息提示完善你的功能代码，这个时候开发已经相当轻松了。
      3。这样写的功能代码用 rcov 测试 test 覆盖率的时候绝对是百分百覆盖的。&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Mon, 04 Nov 2013 16:00:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/15287</link>
      <guid>https://ruby-china.org/topics/15287</guid>
    </item>
    <item>
      <title>37Signals 的新书「Remote」这周二上架</title>
      <description>&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/80d5ac5d4267c3466cf1e2051336b566.png" title="" alt=""&gt;
&lt;img src="//l.ruby-china.com/photo/3846cc9d9217b0254e49e12a26336533.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://37signals.com/remote/?utm_medium=email&amp;amp;utm_campaign=10242013%20REMOTE%20pre-order&amp;amp;utm_content=10242013%20REMOTE%20pre-order+Version+A+CID_2ef6d0334cbe67d4851b55bed25720e7&amp;amp;utm_source=Newsletter&amp;amp;utm_term=these%20fine%20stores#order" rel="nofollow" target="_blank"&gt;http://37signals.com/remote/?utm_medium=email&amp;amp;utm_campaign=10242013%20REMOTE%20pre-order&amp;amp;utm_content=10242013%20REMOTE%20pre-order+Version+A+CID_2ef6d0334cbe67d4851b55bed25720e7&amp;amp;utm_source=Newsletter&amp;amp;utm_term=these%20fine%20stores#order&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;看错，上架是周二，可以买了。&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Tue, 29 Oct 2013 13:56:31 +0800</pubDate>
      <link>https://ruby-china.org/topics/15121</link>
      <guid>https://ruby-china.org/topics/15121</guid>
    </item>
    <item>
      <title>教与学的思考 (关于在线教育)</title>
      <description>&lt;p&gt;我在 51CTO 上放出一些 Ruby 视频课程，通过最近几个月的录制，我有一些感受和心得，分享给大家吧，也算做为在线教育视频课程模式的一些心得。&lt;/p&gt;

&lt;p&gt;原文地址： &lt;a href="http://tao.logdown.com/posts/154747-teach-and-learn" rel="nofollow" target="_blank"&gt;http://tao.logdown.com/posts/154747-teach-and-learn&lt;/a&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;在今年 6 月份，很意外的接到了一休的电话，于是我受邀成为了 51CTO 的 Ruby 课程（诱人的 Ruby）讲师。关于是否接受这个任务，我几乎没做什么思想斗争。从当年认识 51CTO 的运营总监「小废物」，然后在 51CTO 上面写博客开始，再到认识一休以及其他的 51CTO 的其他几个管家，到目前为止已经过了五个年头了，虽然有些年头不在 51CTO 博客上写文章了，但是 51CTO 这个团队给我的感觉，一直是很上进，真正做事的团队，所以在听一休说这个平台上线的时候，我几乎就是立马答应了。自己早年一直有写书的想法，但是一直没有实施，一个是没有好的契机，另一个是自己的懒惰，现在有了这个平台，我也愿意把自己的这个想法去实施了，同时也可以参与并推动 51CTO 学院这样一个在线教育平台的发展中去。当时，我想通过这件事应该会有属于自己的那份收获，当然，不是指钱。&lt;/p&gt;

&lt;p&gt;距写这篇文章，已经过去 4 个月了。让我没想到的是，我之前预想的收获，来的这么快，我想给大家分享一下。&lt;/p&gt;

&lt;p&gt;上学的时候我就对老师这一行当十分讨厌，当然，不是讨厌具体某位老师，而是单纯的讨厌这个职业。所以在录制视频开始，我就给自己定位，不当老师，只作为一个和大家分享所学的好朋友。但是在录制了几个课时之后，我逐渐的发现，老师这个职业，真的不容易，之前讨厌老师那种想法，也逐渐的淡了。之前没有「教」过别人，所以无法体会，录制视频之后，感觉，如果想给别人讲好一个知识点，讲清楚，真的没那么容易，因为这些东西你自己理解了是一个层次，要讲出来，而且还要求别人听的懂听的明白，并达到让别人知其所以然，又是另一个层次。要达到这个层次，必然需要花很多精力去备课，去录制，自己先反复的听去修改以达到自己满意的程度。我开始体会到，成为一个授人以渔的好老师其中的艰辛。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;所以，第一个收获，就是尊重每一位老师，尊重每一位给别人分享知识的人。之前老看盗版的电子书，现在我也开始购买正版了。&lt;/strong&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;备课固然艰辛，但是如果你付出这份艰辛之后，就可以从中获取到另一个收获。&lt;/p&gt;

&lt;p&gt;知识都是相通的，如果你想讲一个知识点，并把它讲全，你固然会运用到其他支援这个知识点的其他知识点，如果做为一个讲师，你不懂这其中的因果关系，就难以给别人讲通那个你要讲的知识点。老聃在「道德经」里说过：「道生一，一生二，二生三，三生万物」，这是万物固有的道，而师者，其实就是这样一个逆向工程，「万物 &amp;gt; 三 &amp;gt; 二 &amp;gt; 一 &amp;gt; 道」，你需要引导学你课程的人，从表象到本质，明白其中的道。&lt;/p&gt;

&lt;p&gt;拿我的 Ruby 课程来说，每个课时的知识点，我都要搞清楚来龙去脉，比如讲线程的时候，就要告诉学员，线程存在的意义，它的出现是为了解决什么问题，人们怎么用它解决这些问题的？有没有什么最佳实践？而在 Ruby 中的线程是如何实现的，Ruby 这门语言，对于线程所要解决的问题，起到多少助力？和其他语言比有何优劣？这个过程，完全可以用哲学上那三个终极问题来形容：「我是谁？我从哪里来？我到哪里去？」&lt;/p&gt;

&lt;p&gt;其实作为讲师的我，在前几年的工作中，虽然也在研究 Ruby，但是我的学习方式，从来没有像录制视频课程这么通透，为了录制一个课时，讲清楚一个知识点，去一个个解开相关问题的因果锁链，我也在学习，但是这种学习效果，带给我的不仅仅是知识，更是一种求知欲，对知识的探索，因为这些问题的因果锁链，越解越多，越多越想解。这种感觉是我在多年的工作中，完全没有体验过的。所以，我也希望通过视频，可以把我这种学习、思维方式带给学员朋友，达到授之以渔的效果。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;所以，这是我的第二个收获，掌握了真正的学习之法，学习之道。除了 Ruby 视频，我也在筹备我的第一本电子书「通往 Ember.js 之路」&lt;/strong&gt;，以完全采用这种思维方式去编写，我希望它会是一部与众不同的技术书。&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;我目前出了两部课程，计划是出四部，因为我也算一个完美主义者，要出就出系统，出完整。&lt;/p&gt;

&lt;p&gt;入门版，目前是免费的，基础提高篇，收费。播放量也有很多，我也建了一个 QQ 群，目的是让我的学员能和我多交流。免费入门篇课程，看的人很多，目前近 3000 多播放量，但是这么多人看，根本没几个人和我反馈，真正和我反馈的只有付费的人。而且，我还发现，很多人不愿意去看视频，不知道是不是觉的免费的东西不值得看还是怎么地，其实免费的课程，我也下了不少精力，看过视频的人，应该能看得出我用的心思。我也在不断的学习国外的视频录制技巧，压缩课程时间，尽力控制时间，让视频内容达到一个精致，不断调整模板，尽力做到让学员视觉上养眼，还有上面所说视频录制的艰辛过程。有的人在群里问一些我在入门视频讲过的最基础的 Ruby 语法知识，很明显就是没有看视频，这让我很受伤，让我感觉录制免费入门课程有点浪费时间。&lt;/p&gt;

&lt;p&gt;直到我昨天看到一篇文章：「高价如何打败低价」，犹如醍醐灌顶（因为是微信看的文章，所以这里不分享地址了）。 &lt;strong&gt;于是我明白了，只有真正想学习 Ruby 的人才来看你的视频，而不是因为你的视频去学习 Ruby。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;所以，我的第三个收获就是，产品，来做给真正用它的用户，价格体现价值。我决定入门篇出完之后，结束其免费，改为付费，只给真正想学习 Ruby 的人。&lt;/strong&gt;&lt;/p&gt;

&lt;hr&gt;

&lt;p&gt;心中所想，写成文字以后，感觉好多了。&lt;/p&gt;

&lt;p&gt;P.S  今天 RubyConf 大会，祝圆满成功啊！&lt;/p&gt;</description>
      <author>blackanger</author>
      <pubDate>Sat, 26 Oct 2013 17:06:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/15050</link>
      <guid>https://ruby-china.org/topics/15050</guid>
    </item>
  </channel>
</rss>
