最近阅读ruby源码非常顺手,这里整理一下阅读心得。
首先,为什么要阅读源码?因为几点:
用到的工具,一定要清楚实现,这样遇到问题能够处理。我在rails开发过程中,遇到一些诡异bug,调试了很久, 最后定位问题到了第三方gem上面。如果我对于它们的代码足够熟悉,可以很快定位到问题点,不需要浪费那么多的时间。
熟悉实现也是一个学习的过程。在看源码的过程中,我对于ruby的使用,如何做架构,都有了更深刻的认识。 写代码水平靠自己磨练,同时借鉴别人的代码也必不可少。很多知识和技巧自己悟出来就慢了,看别人的东西能够学到更多。
然后是重点:如何阅读。
读懂代码之前,我们要把项目的文档看一遍,知道如何使用它。 使用方法是项目的接口,熟悉它们,我们就把“未知”限定在项目的源代码之内, 对于理解源码有了坚实的基础。
之后我们要熟悉源代码的文件树结构。好的项目的文件安排是模块化的, 一个文件就是一个系统模块,ruby项目,一般是一个文件一个类。 这样一个复杂项目,就被切分成一小块一小块人能够理解的部分了。
在这里要停一下,回顾前面看到的文档,列出一些核心的入口, 然后基于这些入口,对于项目的实现提出一些猜想, 然后从这些入口出发,寻找对应的函数,一步步顺着方法调用,看对应的代码。
举个实际的例子。
我看sinatra源码的时候,关注了几个入口:get/post
方法,如何被rack调用。
我会列出猜想:get/post代码应该是记录这些block到一个内部的数据结构中,
在代码里面,有针对rack做一个接口,调用的时候会去解析http请求,分发到对应的block里面。
然后我开始用find
和grep
寻找get
,遇到函数调用,就用同样的方法一路看过去。
最后发现get
方法实际上是给类创建了一个方法:#{verb} #{path}
,然后绑定它。
和我想的不太一样,并不是用一个数据结构。
然后我又去看rack调用过程,最后弄清楚了如何分发请求,如何调用请求,以及在执行中快速跳出, 并且学到了一个小技巧。
在阅读源码的过程中,我弄清楚了:调用栈,数据结构,类架构,以及验证了阅读代码前的各种猜想, 通过了解里面一些看不懂的部分,学到了新的知识。整个顺藤摸瓜过程是非常愉快的。
对了,最后还有一点,记得记笔记。研究过程不记录就白研究了,下次你是绝对想不起来的。 我会把上面跟踪函数调用栈中遇到的核心区块记录下来,整理成一个执行过程文档, 下次需要的时候直接看这个文档就可以了。这是一个示例(当然只有我自己才看得懂啦):
1 2 3 4 5 6 7 8 9 |
|