我们在做网页的时候经常有这样的需求:

{'hello': 'world', 'good': nil, 'bye': 'bye'}

需要处理为

{'hello': 'world', 'bye': 'bye'}

有人说,这还不简单,使用

{'hello': 'world', 'good': nil, 'bye': 'bye'}.compact

不就得了?嗯哼,那这个 compact 到底是哪来的?这是一个问题.

同时使用 Ruby on Rails 和 Ruby 的人单凭记忆很难区分 API 到底来自哪,这里有个有趣的测试,试试看自己分得清吗?两者的语法高度相似,甚至发展也互相影响,我们接着看看如果不用 compact 该怎么写.

# Ruby 1.8.7 及以上
h = {'hello': 'world', 'good': nil, 'bye': 'bye'}
h.delete_if { |k, v| v.nil? }
p h
# Ruby 1.9.2 及以上
h = {'hello': 'world', 'good': nil, 'bye': 'bye'}
p h.select! { |k, v| !v.nil? }
# Ruby 2.4.0 及以上
h = {'hello': 'world', 'good': nil, 'bye': 'bye'}
p h.compact!

是不是越来越简单了?我们再来梳理下整个过程:

2014年,tinogomes为 Ruby on Rails 提交了一个 PR,这就是大家直接在框架中调用的 compact .每个方法的实际内容只有一行,感兴趣的可以看看.

2015年,此功能由 Ruby Core 团队接受,最终在 2.4 版本正式发布.

这就是一个框架如何反向推动语言的例子.整个事件中可能最值得吐槽的就是 Ruby on Rails 起错名字了,分明应该叫做 Rails on Ruby 才对嘛~