今天要交付7寸笔记本测试程序的第二版。这是我这一个月来主要工作所在。我采用lua+curses库的方法,对其界面和操作方式进行了大胆地改进,效果非常不错。
开始,我用的是 luacurses封装,使用其来开发的过程中就发现一些细节问题,觉得是这个库不完善所致,想不到最关键的一个BUG就在今天凸现出来,运行到一半的时候,整个程序segmentation fault挂了,这样一种严重的错误,真是恐怖。当时头脑,一下子就懵了,这可乍办。感觉到一个月来的工作几乎前功尽弃了。在极度痛苦之中,我镇定下来,分析产生这个错误的原因。
出现这个问题,有可能是luacurses库封装得不行,造成内存泄漏,运行了一定时间就崩溃;也有可能是Lua本身的垃圾收集器出问题了,难道Lua真的不适合做大型开发(让我不禁对Lua的前景黯然了)?
不过,一想到那个大型的kepler和sputnik工程,用纯Lua写成,运行得如此良好,基本上可能排除Lua解释器和垃圾收集器本身的问题。于是,将焦点集中到curses库的封装上来了。
针对现象,我提出了4个努力方向:1. 看Lua中有无卸载库的语句。在中途运行了几个项目之后就卸载一次,然后再重新加载,看能不能解决问题;2. 看Lua中有无垃圾清理的上层语句。在中途运行了几个项目之后就清理一次,看有没效果;3. 更换 curses 封装库;4. 是不是Debian的Lua有问题的原因,自己去下载源代码,重新编译看行不行;
查了《Programming in Lua》后,很快就放弃第一和第二个想法了,第一个想法答案是没有,第二个想法答案是只在C语言接口层有相应操作,于是考虑第3个方案。
当时想到 curses 库的封装以前曾下过几个不同的封装包。于是马上查了查,发现有一个叫 lcurses,另一个叫luaNcurses。比较了一下,LuaNcurses工作量做得比较少,感觉才刚刚开始;而lcurses做得比较多,甚至连CUI都做了少量工作。于是详细读了一下它的说明,发现它的API封装得与 curses库有些许不同(这也是当初没有选择它的原因),但写得算是相当地好的。一看作者,发现是大名鼎鼎的Diego(就是IM的作者吧),不由得相信了几分,觉得这应该是一个能用的库了。
修改了它的Makefile后,编译成功了,并按照它的API修改了一下原来一个测试用例,发现还真好用,以前在Luacurses里面发现的一些问题,这里面也不曾出现了。效果非常好。于是决定马上修改我的 nb-7suite-lua。
真感叹自己当初的英明,把所有直接调用库的语句都用自己的一套API封装起来了,全都实现在common.lua文件中。这样修改起来就非常方便,只需改common.lua文件,其它几十个文件一个都不需动。太棒了!当初以为更换一个库很麻烦的,因为API不一样,结果只用了十分钟就更改好了,最后调试再花了十来分钟,一切搞定。
经测试,再没出现 segmentation fault 错误了。谢天谢地!
如此可见,细节无关性和细节集中封装性设计的优点!
另外,还有一个经验就是,开发过程中所写的一些测试代码,要集中归到一个文件夹中去,而且要编号,不要用完一次就删掉了,这对后续的开发是很有帮助的,因为后面的新功能可能需要先测试后再加到主代码中去。