All Stories

LuaJIT2与Luabind打架了

  其实这个问题老早就有了,当时还在Lua的maillist上提过,不过当时我只是发现LuaJIT2在执行Lua脚本时,如果Lua脚本调用了不存在的C函数时会使宿主崩溃,Mike Pall同学(LuaJIT的作者)倒是很爽快地解决了这个问题。后来发现,Mike Pall解决的只是一部分,我这里因为用到了Luabind,通过Luabind来调用执行Lua函数,如果Lua脚本又调用到不存在的C++函数,进程就会无声无息地退出,而如果是官方Lua的话,则是会老老实实地打印那些出错信息出来。   昨天忍无可忍了,就又向Lua maillist发了封邮件,今天发现Mike Pall和Daniel Wallin(Luabind的作者)争起来了,呵呵。Mike Pall说问题在Linux上和Windows/x64上都没能重现,不知道Windows/x86出了什么问题,可能是Luabind重复抛出异常了,Daniel Wallin则说Luabind只是简单地调用了lua_error,他倒是能在虚拟机的Windows环境下重现问题,最后他又给出了一段简化后的代码,只要lua_error调用后面有C++对象的析构,LuaJIT就会出问题。   我倒是偶然看到今年1月份的Lua maillist上的邮件,Mike Pall曾经说过Windows/x86上MSVC实现try/catch是用SEH实现的,这个LuaJIT处理可能有点问题。但他后来的邮件中好像又说在新代码中已经解决这个问题了。我于是用MinGW试了试,GCC 4.4.0编译出来的,确实是没问题的呢!   不过最后,又看到Mike Pall好大一篇解释,最终结论是建议所有用户都升级使用x64,囧!

入沪通行证

  刚才有那么一刹那,突然很害怕,不知道今天做了什么,几秒钟后反应过来,今天出门了,去办入沪车辆通行证了,现在这记性,真让人无语。   总的说来是比较顺利的,昨天在网上看过大致的要求,今天先跑去东关派出所,这是离我们家最近的派出所了,顺便试了试前天买的导航,除了我们村认不出来外,其他的都不错。到了东关派出所,结果被告知,因为车主是我妈,而我妈的户口是在百官的,所以得去百官派出所办,而且因为授权给我开,所以我得有临时居住证。有点出乎我的意料的是,临时居住证的办理非常快捷,只要填一张表,交两张一寸照就可以了。而我没有一寸照,就跑到东关街上那家主人本来是棉纺厂里跟我们是邻居的照相馆里立马拍了照。话说现在的拍照也太方便了,拍完后直接拷到电脑上用Photoshop改了一把,再用打印机打出来就行了。然后再折回派出所,那里的姐姐动作麻利地把其他事情一会儿就搞好了,临时居住证也是从打印机里打出来的。接着就直奔百官派出所,这时导航就比较傻了,我估计是地图没有更新,一直指向另一个派出所了。到了百官派出所,人也不多,那里的mm拿出三张纸来让我填,然后去旁边的复印店里复印了一下相关证件,就被告知等3天后就可以取到入沪通行证了。还是很顺利的啊!   我真的投入进去了,不顾一切地投入进去了,不怕遍体鳞伤,不怕鲜血淋漓,为了爱,我要勇敢!

增强Code Snippet

  本来这是打算在上周五完成的,结果上周五又开小差搞界面去了,周六周日又跑去魔都了,于是就拖到这周了。今天刚开始的时候还有点惧怕的,怕是实现难点有点高,甚至又冒出过放弃的念头的。后来还是硬着头皮做一点是一点,结果还不错,比想像的要容易一些,已经能达到90%的计划中的程度了,剩下的10%么,从个人感情上还是从策略上,都应该放到后面的版本中实现了。   下面先说一下最终的表现吧。   前一个版本,code snippet使用的展开缩写的快捷键是Ctrl+,,这次把这个快捷键换到Ctrl+;了,那是因为另外又增加了两个操作,这两个操作是正反对应的,于是分别占用了Ctrl+,和Ctrl+.。正常的操作方法是,假设在编辑Lua源代码时,输入for,这时光标停在最后一个字母r的后面,按快捷键Ctrl+,,会自动将for展开为比较完整的for i = 1,10 do…(省略号表示后面还有些内容,这里不影响说明,就不列出来了)并选中for后面的循环变量i。到这步为止,相比上个版本的实现,只是增加了选中循环变量i的这步操作,但也已经方便了用户可以不再手动移动光标位置来修改变量名称。接下了,就是新增的两个占用了快捷键的操作,即Ctrl+,和Ctrl+.,分别是向左或向右跳动选中1和10。也就是说,在这次for展开后,共有3处可能被自动选中,即i、1、10,至于每次选中哪处,可以通过快捷键Ctrl+,和Ctrl+.来修改。这是基于这样的应用场景:在for循环中,基本的循环结构是自动补完了,但实际上循环变量和变量的初始值和终结值是最可能需要根据情况修改的,于是编辑器就可以通过快捷键快速选中这些部分,而不用再通过鼠标或方向键等常规方法移动输入光标进行修改。这就是最终的表现。   接着简单记一下实现的过程。   因为从整个程序的实现架构上的原因,此功能的实现一部分由Lua脚本完成,一部分由C++完成。首先是修改了code snippet的模板,如上例中的for,在模板中的定义是for ${1:i} = ${2:1}, ${3:10} do…(省略号表示后面还有些内容,这里不影响说明,就不列出来了)可以看到有3处用${}包括的内容,这些内容的都用一个冒号分隔,冒号前面是一个编号,冒号后面是最终展开后填入到编辑器中的内容。编号用于按快捷键Ctrl+,和Ctrl+.时进行排序,Ctrl+,则从大到小跳转,Ctrl+.从小大到跳转,初始状态时选中编号为1的部分。在for后展开snippet,是用Lua脚本完成的,那会先从模板配置文件中找到缩写对应的模板,然后将${}部分全都提取出来并替换成冒号后面的部分内容,并根据当前编辑器的插入位置重新计算和修正每个${}的位置信息。这些位置信息用于后面的选中功能。然后把所有这些信息都存入C++实现的编辑器对象中,在C++实现的编辑器类中会有几处事件通知处理。一处是刷新UI时,更新当前光标位置,如果当前光标位置已经不在任何一个${}的范围内,那么本次code snippet展开就算完成任务了。另一处是编辑器内的文本修改,如果有新增或减少文本,那么要修改当前光标所在的${}的长度(这个长度在选中文本时需要用到),并修改该${}位置后面的所有其他${}的起始位置。只有这样,才能在修改了一处${}后,仍能继续正常地在各处${}间来回跳转。好了,基本的思路就是这样了。   题外话,想说一下,在文本处理方面,脚本语言确实比C++要方便一些,比如查找替换${}部分,在Lua中实现的模式匹配就很好用。

新工具栏

  昨天偶然发现CodeLite已经升级到2.5版本了,作者还真是孜孜不倦啊。下载下来看了一下,发现最明显的是界面上的变化,工具栏变漂亮了。于是我又好奇心起来了,找来它的源代码看看,原来是用wxAuiToolBar类而不是原来的wxToolBar。于是昨天我先在自己的程序里把主工具栏也换了一下,感觉是很爽。昨天还加了最近打开的历史文件记录和解决方案记录,一直弄到晚上9点才基本搞定,一开始没搞清楚怎么处理2个wxFileHistory对象。   今天开始着手增强Code Snippet。前天已经想通了,现在的插件机制基本上算得上强悍,就不用完全照搬TextMate的Bundle了,只是Tab trigger还是不错的。我的决定只要把code snippet部分做得跟Tab trigger差不多就行了,以后再完善一个插件机制,提供一个插件开发包就行了。   今天写代码,看着焕然一新的工具栏,以及方便的最近打开文件菜单,心情非常好,code snippet的预处理部分基本上完成了,明天只要加上快捷键,可以进行跳转就OK了!后来又觉得应该把TeX的符号工具栏也用新式的wxAuiToolBar,由于它跟wxToolBar的接口有点区别,所以自己从wxAuiToolBar继承下来创建了个新类,主工具栏和符号工具栏都可以使用新界面了,感觉不错!   看来得多找些更新积极的开源的项目,多学习学习那些源代码啊。

两个月计划

  想到实现Bundle,是个比较大的挑战,有些部分必然会跟编辑器核心结合得比较紧密,对于我这种直接使用Scintilla控件实现的方式,很有可能需要修改Scintilla的源代码提供必要的支持。今天一想,其实如果基于我现在的Code Snippet的思路做下去,是很难做到TextMate的地步的,因为Bundle能完成的功能很多,输入输出条件也有好几种,而code snippet只是其中的一种而已。如果只是沿着把Code Snippet强化这个方向发展,最多实现到TextMate中Tab trigger的那种地步,而这些正是我之前一直在考虑的以为是Bundle的东西。小瞧了啊!没办法了,一步一步来吧。   昨天在QQ上跟人交流,知道一个诺基亚的手机应用开发大赛,到6月10日截止提交作品,到9月评出结果。现在算来还有足足2个月,不过我并没有好的题材。他是做图像处理方向的,而且是用QT的,所以移植到Nokia的手机上应该工作量比其他人小多了吧。另外他还给我看了一个老外做的画图软件,那界面真是赞啊!如果不是做像IDE这种严肃型的软件,其他的大众类软件真的得好好设计一下界面。   前些天Firefox自动升级到3.6.2后,看到Firefox也用twitter/facebook/blog进行推广了,看来这是大势所趋啊。之前试过几次想创建一个组织型的Facebook账号,结果一直没成功,今天发现原来是创建错类型了,Facebook有专门的为产品/组织等非个人形式的个体创建页面的入口。于是今天就在网站上加了twitter和facebook的链接,至于blog嘛,众所周知世界上最成功的blog营销案例,在软件行业应该算Joel on Software,不过Joel在那篇宣布以后不再写blog的文章中提到过,要靠blog聚集人气,不光要写自己公司的产品,还要写关于软件开发的方方面面,这样才会吸引各种相关读者的讨论。可是,我现在的致命缺陷是,我当前的英文水平完全不够用来写blog,真郁闷啊!

准备实现Bundles

  昨天晚上咬牙把所有的图片都修正了一遍,基本处于可用的状态了,终于撑过这段繁琐枯燥的工作了。今天又添加了几个新建项,上次发布的时候把这个忘掉了,这次补上。不过实现得有点儿问题,在第一次显示的list view中只要是有多个图标的,总是会在最开始留出那个数目的图标的位置,真郁闷,心烦意乱地调了一下午,也没进展,先不管了。   接下来的任务是实现一个类似TextMate的Bundles机制,这需要好好设计一下,实现成什么样,怎么实现。最近在纠结的问题是,快捷键要不要换掉。TextMate和e都是用Tab的,而且不支持Shift+Tabe。我在之前的版本实现code snippet时,用了Ctrl+,这组快捷键,而且我觉得支持反向跳转似乎很炫,呃,目前确实只能用“炫”来形容,因为不知道实际使用过程中到底有没有用。

自动化,自动化!

  昨天提到从抠图片,到添加到程序中,一共要处理500多个图标,很大的工作量,而且太枯燥机械了。今天看到MiloYip大大的留言,恍然大悟,我怎么就一直没想到把这个过程自动化一下呢!   今天上午的时候还在老老实实地把图标一个一个加入到程序中,这有两步操作,一步是添加XML描述,另一步是添加Lua响应函数。一上午,总共添加了53个图标,到吃中饭的时候自己都觉得效率太低了。在MiloYip大大的提示后,下午用Lua写了几行代码,花了2个小时左右,把剩下300多个图标全都添加进去了。以前真是太傻了,多花了不少时间啊!   剩下的工作就是把那些图标稍微都修正一下。   从这次事件可以看出,我的相关技术敏感性还不够,缺少自我改进意识。

每天完成固定工作量

  这几天一直在搞LaTeX中的一套符号工具栏按钮,符号一共有500多个,全都放在工具栏上,就需要500多个图片作为按钮图标,这实在是一项繁琐的工作。   图标是从另一个软件中通过截图抠出来的,每个图标截出来后,要用图标处理工具把周围其他的颜色都去掉,然后可以添加到我的程序中,而我的程序又分两部分,一部分是xml描述,另一部分是功能代码,这样的操作需要重复500多次。   这样已经有6天了,而完成的只有100多个图标吧。当然这5天里还包括了其他的一些事情,比如这个工具栏以前是没有的,放在了另外的位置,于是主框架上C++代码也加了一些,这些编码时间应该是接近2天了。还有就是之前在抠图标时方法不是很高效,花了一些时间,后来找到一个比较省事的办法,人也轻松多了。   总的说了,每天要完成固定的工作量,这样日积月累下来,总有完成的一天,而不会到时候进行回顾,发现自己不知道做什么去了。也许每一天看起来做的事情并不多,但贵在坚持。

[转][译文]程序员能力矩阵 Programmer Competency Matrix

见了这个表格好几次,这次终于忍不住了,本来我是不太乐意转帖文章在这里的,但这次稍微破个例,但愿不是个开头。我自己基本在level1和level2之间徘徊,需要加倍努力啊! 注意:每个层次的知识都是渐增的,位于层次n,也蕴涵了你需了解所有低于层次n的知识。 计算机科学 Computer Science   2n (Level 0) n2 (Level 1) n (Level 2) log(n) (Level 3) Comments 数据结构 不知道数组和链表的差异 能够解释和使用数组,链表,字典等,并且能够用于实际的编程任务。 了解基本数据结构时间和空间的折中,比如数组vs 链表,能够解释如何实现哈希表和处理冲突,了解优先队列及其实现。 高等的数据结构的知识,比如B-树、二项堆、斐波那契堆、AVL树、红黑树、伸展树、跳跃表以及前缀树等。 算法 不能够找出一个数组各数的平均值(这令人难以置信,但是我的确在应聘者中遇到过) 基本的排序,搜索和数据的遍历和检索算法。 树,图,简单的贪婪算法和分而治之算法,能够适度了解矩阵该层的含义。 能够辨识和编写动态规划方案,良好的图算法知识,良好的数值估算的知识,能够辨别NP问题等。...