Yuguo.us

Ruby漫谈

Introduction

user

余果

全栈工程师,《Web全栈工程师的自我修养》作者。


Featured

back-end

Ruby漫谈

Posted by 余果 on .

最近一个月都没有写博客,但是也许会有人从自动发送的rss feed中发现我不小心发布了两篇草稿,然后又删除了。因为我在跟一个朋友一起在做一个有趣的项目:Gitblog,在调试的过程中不小心发布了两篇测试博客。

这位朋友hyspace是我在Github上物色全栈工程师的时候找到的一个有趣的家伙,但是他不能来我厂工作,因为马上准备要出国。不过他刚发布的一个开源项目很有趣,而且我也一直想用更好的方法来发布github pages博客,所以就跟他一起在做这个项目。

招聘小广告:我们仍然在招聘前端工程师,任何其他方面的加分项都会考虑在内。有C++经验?设计能力?微博段子手?硬件?全部加分。所以不要问我有哪些硬性要求了,简历发到我邮箱,我们会给你评级,并且能力越高,评级越高,能力不足,也有对应的岗位。

虽说是合作,但我更多的是学习和请教,因为项目是用Angular和coffee实现的Single Page Application,而且没有后端代码,项目本身托管在github pages上面。而我没有Single Page Application方面的经验,更多地还是习惯服务器端的MVC架构,而且coffee不熟悉,可读性也够呛。我花了很多时间看教程,然后熟悉已有的项目结构。这就是为什么接入了一段时间,其实代码修改量还是很少的缘故。

话说回来,最近工作上也有很多很关键的任务,需要我做一些工具类和后台类的开发。我熟悉的服务器端语言是PHP,但是不太适合服务器计算量很大的项目,所以我需要把目光转向一些不太熟悉的领域。

我把项目语言锁定在Python和Ruby之中,因为这两者都是对程序员很友好的语言,也有很活跃的程序员社区以及开源库的支持。我最终决定用Ruby,主要的原因就是Python是一条大蟒蛇,Ruby确是一颗闪闪发光的红宝石。

开玩笑了,其实我觉得二者都是不错的选择,我只是选择了一个之后就尽快开始了,因为从立项到最终时间点我只有几天的时间。

花了半小时阅读Ruby官网的 入门指南之后,就开始写一些hello world和对应的测试。因为我的工具最终会分发给很多合作伙伴去用,所以我准备以gem的方式去发布。花了几个小时看gem的编码规范和发布流程,最终两天内就写出了一个根据目录去压缩图片的工具套件,可以在这里看看源代码github,也可以在rubygems上查看。工具名叫ii,是image idea的缩写,之所以使用这么简短的名称,是因为这样就可以在命令行里快速输入了。

ii可以说是一个非常简单的DSL(Domain Specific Language)雏形,所谓DSL,是指为特定领域所专门设计的词汇和语法,简化程序设计过程,提高生产效率,同时也让非编程领域的专家也能直接描述逻辑。

举个栗子,如果你熟悉服务器端.haccess的配置,那么.htaccess的语法就是一种DSL,它的目的很专一,就是用来配置服务器的一些url操作,对于不理解服务器的用户也能对照说明书来编辑。

正则表达式,是一种DSL,它的目的很专一,用来描述和匹配字符串。这种DSL已经接入到几乎所有的通用编程语言中,比如JavaScript、PHP、Ruby、C++等,而且它是使用了自己发明的语法,所以称为“外部DSL”。

内部DSL是指根据已有的通与语言的语法来设计的一种语言,而且往往会伴随一个对应的工具,比如Rake就是类似Make的一个工具,它会分析文件的依赖关系,并自动执行程序的编译和连接等操作。用来描述这些操作的配置文件叫做Rakefile,Rakefile同时也是一个合法的Ruby代码。所以我们说Rake是一个基于Ruby的内部DSL,并且伴随一个Rake工具来实现特定的功能。

DSL是一个非常有趣的话题,Ruby之父松本行弘的一本书《代码的未来》有一个章节专门讲DSL的话题,后面还有更复杂一点的元编程,我必须承认我暂时看不懂。

我对ii的期望目标是一个在图形处理方面的有特定功能的软件(满足我厂现在的一些图形方面的需求),它的目的是给合作伙伴去用。但是远程指导他们用的时候,我发现有很多问题,因为命令行的方式是适合程序员的,但是普通用户更多是习惯GUI,我几乎要从用户权限、目录操作方面开始教,学习成本很高。而且图形方面的处理需要安装很多底层依赖,让合作伙伴去安装非常困难。

考虑再三,我决定搭建一个web API的方式,然后再接入一个页面来让用户去操作。所以接下来的两周我都会全力投入这个项目的开发。

谈谈我学习Ruby这一周以来的一些感悟。Ruby的设计原则就是为了最大的灵活性,完成同样一个任务有多种方法。比如最简单的函数调用:

call_function(foo, bar)

也可以不要括号,用空格跟逗号来隔开多个参数,就像coffee那样:

call_function foo, bar

但是这样可读性其实并不高,所以Ruby才更需要统一编码风格。我查了一些Ruby编码规范。这是一篇很长但是很值得一读的规范

而且Ruby允许你对官方的类和模块进行无条件的修改和扩展,这种灵活性导致了一些很逗比的情况,比如在Rails中你甚至可以使用以下代码表示20小时之前:

20.hours.ago

这种表达非常适合英语思维的人,而且似乎有点不可思议。但是了解背后的原理之后,就觉得恍然大悟了,首先扩充整数类中的hours方法,对20.hours返回72000(3600秒×20)这个值,ago方法又返回该秒数之前这一时刻的一个Time对象而已。

有趣的是语言的发明人是日本人,但是在欧美有很多粉丝,他们热烈地讨论能在Ruby的语法框架下把Ruby改得多像英文。

Ruby也是以代码量简洁著称,比起Java、PHP这些老语言简洁非常多,比起新的语言比如Objective-C也是更胜一筹,比起XML这种外部DSL同样更简洁(XML有大量重复的嵌套标签),所以在用它来设计内部DSL的时候,有天然的优势。

最后,以据说是贝尔实验室的一句名言结尾:

库设计就是语言设计。 Library design is language design.

比如jQuery的设计就是对JavaScript的语言扩充。

user

余果

https://yuguo.us

全栈工程师,《Web全栈工程师的自我修养》作者。