一月 27, 2006

C++ Code Generation with Elisp

尽管使用Emacs有些年头了,但是在读PHP Code Generation with Elisp之前,我还没意识到可以在Emacs里做代码生成这样的事情。

用了这么久Emacs,感觉唯一不如其它IDE的地方就是没有生成class的wizard。于是只好每次不厌其烦的在头文件里写完类定义,再到C文件里写成员函数的定义,每个字母都是手工敲进去的,最多也是复制粘贴。直到有一天,我对自己说:“够了,为什么不懒一点呢?”于是,下面就有了下面这段代码。

(defun make-cpp-function-definition (buffer class-name start end)
"generate c++ function definition and insert it into `buffer'"
(interactive "BAppend to buffer: \nMClass name: \nr")
(setq function-declaration (buffer-substring-no-properties start end))
(setq function-definition nil)
(defun iter (pos)
(if (string-match
"\\(?:\\(?:virtual\\|inline\\|static\\)[ \t\n]*\\)?\\(?:\\(\\(?:const[ \t\n]*\\)?[^ \t\n;* \t\n]*\\([^;]+\\)\\);"
function-declaration
pos)
(progn
(setq return-type
(match-string 1 function-declaration))
(setq one-function-definition
(match-string 2 function-declaration))
(if (equal class-name "")
(setq one-function-declaration
(concat return-type "\n" one-function-definition))
(setq one-function-declaration
(concat return-type "\n"
class-name "::" one-function-definition)))
(setq function-definition
(concat function-definition
one-function-declaration "\n{\n}\n\n"))
(iter (match-end 0)))
'()))
(save-excursion
(iter 0)
(set-buffer (get-buffer-create buffer))
(setq pos (point))
(insert function-definition)
(indent-region pos (point)))
(if (one-window-p)
(split-window-vertically))
(switch-to-buffer-other-window buffer))

用法如下:

  1. 把这段代码复制到你的.emacs文件里,这样在每次Emacs启动时都会自动安装该段代码。
  2. 如果不想重新启动Emacs的话,可以手动安装该函数,方法是把光标放在最后一个右括号后面,然后C-x C-e安装,更方便的方法是使用C-M-x,因为这个命令只要求光标在要安装的函数体内就可以了。
  3. 随便打开一个buffer,写一个class,如:
    class A {
    public:
    void print () const;
    virtual int get_constant () const;
    };
  4. It's show time now. :-)
  5. 选中两个成员函数(mark the region in which two member functions are),然后运行M-x make-cpp-function-definition,该命令会问两个问题,第一个是自动生成的空成员函数体要放到哪个buffer里,你要给出一个buffer,如果这个buffer不存在,Emacs会创建一个。第二个问题是class的名字是什么,对于这个例子来说,你只要输入A。当然,如果我足够牛的话,可以让这个函数自动发现类名,可惜我现在还是个菜鸟。:-(
  6. 回答两个问题后,生成的代码会插入指定buffer的光标所在处。这就是说,如果这是一个已经存在的buffer,你应该在运行该函数前选好光标的位置。生成的代码是这个样子:
    void
    A::print () const
    {
    }

    int
    A::get_constant () const
    {
    }
  7. 最后,当前frame会垂直分成两个窗口,分别包含类和成员函数体。

这个函数有个bug,就是它无法正确处理构造函数和析构函数。当然,你仍然可以用它,然后稍稍修改一下生成的函数体,这样也比一个字母一个字母敲要好。另一个bug是关于缩进的,因为缩进是跟buffer的mode相关的,所以如果要插入函数体的buffer不是c++ mode,那需要手工修改一下缩进。当然,在Emacs里,这很容易。

注:由于屡次受到垃圾评论的骚扰,本贴评论被关闭,有事发邮件。

一月 25, 2006

Install Perl Module from CPAN

我们的测试过程大部分已经自动化了,但还是需要在每次代码更新后手工提交。虽然我只负责其中一种测试,但对时刻关注是否有代码更新感到十分厌烦,有时候甚至会忘记为某次代码更新做测试。于是想着这个过程是否也能自动化。

我负责的测试是以web方式提供的,每次都是打开浏览器,填几项内容,然后提交,测试跑完后会用email的方式发出测试报告。因此,我的自动化要做这么几件事:

  1. 定期检查是否有代码更新。因为测试十分耗时,所以两次代码更新之间的间隔会比较长,所以我认为每一小时检查一次就足够了。
  2. 如果发现有代码更新(我们每次代码更新都会修改一个特定的文件,因此只要检查那一个文件就可以了),就更新所有代码,然后编译。
  3. 提交测试。

为了实现第三步的自动化,我决定使用LWP这个Perl Module。但是Cygwin本身并没有这个module,必须要自己装。下面是我安装这个module的方法。

  1. 首先配置CPAN Module,方法是在bash下面运行
    $ perl -MCPAN -eshell
    配置过程会询问一些问题,其中CPAN的镜像可以选择http://cpan.linuxforum.net/
  2. 接下来要更新CPAN Module,而不是直接装LWP。否则会遇到undefined subroutine &Digest::base::new之类的错误。方法是运行
    cpan> install Bundle::CPAN
    这一步是关键,切记切记。我开始不知道,还在网上搜索这个错误信息,发现有人说是Perl的问题,我就把整个Cygwin更新到1.5.19.4,结果啥用也没有,还把其它东西弄得一塌糊涂。
  3. 装好新的CPAN Module,先退出,然后再运行1里面的命令进入CPAN的shell,这时就可以装LWP了
    cpan> install Bundle::LWP
    安装Bundle::LWP意味着不仅安装LWP,而且安装它需要的其它module。

一月 24, 2006

Setup Exim from Cygwin to Send Email on Windows

其实设置很简单,运行

$ exim-config
逐一回答问题,绝大多数使用默认的选择就可以。设置好后Exim就成为一个Windows的服务程序,打开这个服务就可以了。Cygwin提供了一个叫作"email"的程序,用来在命令行上发邮件,它有一个-html选项,可以用来发HTML格式的邮件。如果邮件事先存在一个文件里,可以用管道的方式将其内容作为邮件正文发出,如:
$ cat content.html | email -s "mail subject" -f sender@domain.com receiver@domain.com
如果你真的运行这个命令,会发现它报错说/usr/lib/sendmail不存在,即使做一个符号链接到/usr/bin/exim也没用。经过反复尝试,我发现可以直接将exim-x.xx-x.exe复制为/usr/lib/sendmail就可以了,在我的机器上是这样操作的:
$ cp /bin/exim-4.60-1.exe /usr/lib/sendmail.exe

我就是用这两个程序把测试报告发出来的。

一月 23, 2006

List of Firefox Extension I use

很多人都列这个,咱也凑个热闹。:-)

Enabled Extensions: (15)

Bloglines Toolkit 1.6.2 这个版本修正了“订阅链接”没有响应的bug,经常使用。
Copy Plain Text 0.3.2 向Rich Text Editor里复制东西时特别有用,才装不久。
del.icio.us 1.0.2 经常使用。
del.icio.us toolbar 0.051 不用了,改用上面一个。
Duplicate Tab 0.7 复制一个tab到一个新的窗口,早就期待这种功能了,才发现不久。
Flashblock 1.5 似乎和NoScript冲突。
Forecastfox 0.8.2.5 经常使用。
Google Toolbar for Firefox 1.0.20051122 翻译功能不错。
Greasemonkey 0.6.4 赶时髦,刚装的,没用过。
ListZilla 0.7 用来导出这个列表
NoScript 1.1.3.5 禁止运行脚本,经常使用。
Performancing 1.0.1 写blog,用过一次,才装不久。
Restart Firefox 0.3 菜单项挂在“文件”下面,才装不久
SessionSaver .2 0.2.1.031 太有用了,才装不久。
Talkback 1.5 忘了什么时候装的。
Disabled Extensions: (1)

Mozilla Calendar 0.8.3+ 这个版本和FireFox 1.5不兼容,等待更新。

一月 20, 2006

Experience on Bloglines

今天在Bloglines里面看自己的blog时突然发现,我的blog标题“懒惰的程序员”对应的链接不是http://www.wanglianghome.org/blog/,而是http://netcasper.blogspot.com/,那是我重定向http://feeds.feedburner.com/casper之前的主页。于是在它的Contact Us页面发了一封信,请他们帮忙改掉。本来以为会有个地方给用户提交bug,可惜没有(或者我没找到?),只发现这个发email的地方。不过想想也对,发email大家都会,提交bug就有点专业了,不是干这一行的恐怕光是理解这个概念就够受的了。

用了Bloglines这么久,最想要的就是删除功能,因为FeedBurner出来的东西有时会有乱码,这些乱码又不会自动换行,当我想浏览从前的帖子时,总是要拖动水平滚动条,很麻烦。也许这种需求有些怪异,就像我觉得删除GMail里的信件就有点奇怪。

另外对Bloglines的搜索功能也不太满意,我明明订阅了Performancing.com的blog,可就是没搜到The End of The World这篇文章,还是用Google的Blog Search才找到。

就在我写这篇文章的时候,Bloglines的界面突然变成一种不认识的语言。:-(

最后,我希望各位Bloglines的用户能尽量公开自己的内容,比如我发现有5位Bloglines用户订阅了我的blog,但只有CharlesLihui一个人公开了他的信息,而我通过这种方式发现了他的blog,并订阅了其中2个——尾鱼头尾鱼头之云海翻腾

一月 19, 2006

Always Produce

今天读了Paul Graham的美文"How to Do What You Love",深以为然,打算在这个周末把它翻译出来,与更多的人分享。下面这段话是让我感触最深的段落之一。

"Always produce" is also a heuristic for finding the work you love. If you subject yourself to that constraint, it will automatically push you away from things you think you're supposed to work on, toward things you actually like. "Always produce" will discover your life's work the way water, with the aid of gravity, finds the hole in your roof.

这也是我今年对自己的要求,多做实事。特别地,作为一个程序员,要多写代码,多写心得。德鲁克在他的著作《卓有成效的管理者》中说做事情要“重视机会,不能只看到困难”,还说“目标要高,要有新意,不能只求安全和方便”。所以今年一定要志存高远,敢想敢干。其实我刚刚就碰到一个自以为很难解决的问题,拖了两天才动手,哪知很快就解决了,顿时信心大增。看来很多人终其一生没有什么成就,不一定是因为他们没有能力,而是因为他们不敢想。

这段话对我触动很深,使得我顿时中断阅读,转而去看代码,一直看到心安之后才返回来把文章读完。:-)

一月 18, 2006

About Me

王亮,1977年生于黑龙江省安达市,现租住在上海。不知何时起,深深爱上了编程这个行当,愿意做一辈子程序员。对程序设计语言的表达方式和表达能力非常感兴趣,能够使用C++Perl写程序,但只会用Emacs写程序。最钦佩的人是Richard Stallman,梦想成为自由软件运动的一员。有电脑一台,装了Fedora,希望能够利用业余时间多学点东西。

1996年考入浙江大学计算机系,2003年研究生毕业,离开了生活7年的杭州,来到上海,加入英特尔(中国)有限公司。2005年12月公司搬到闵行区紫竹科学园区,同时更名为英特尔亚太研发中心有限公司。2006年11月9日离职,共1320天。于12日正式加盟Marvell。

痛并快乐着的国米球迷。小时候打过乒乓球,大学时开始踢足球,上班后基本没运动过,一度腰背酸痛,但愿不要落下职业病。工作的第五年头,终于开始严肃地锻炼啦!

我的Svn Repository

我工作过的两个公司:

我的简历——中文英文

我的性格属于九型人格中的5号——观察者

我的feeds一览表

我下载电子书的地方

我在其它地方写的自我感觉还不错的blog

我的年度总结



mount -t ext3 /dev/sda9 /usr

突然发现根目录所在的分区已经没有空间了,于是打算将一部分内容移出来,挂在别的分区上。

开始尝试移出/usr/lib,可是没有成功,很多服务和应用程序找不到库文件,或者报告“权限不够”之类的错误信息。于是只好将整个/usr目录全部移出来,这下终于成功了。

下面是我执行的命令:

$ mv /usr /usr2
$ mkdir /usr
$ mount -t ext3 /dev/sda9 /usr
$ cp -R /usr2/* /usr/

然后在/etc/fstab里添加相应的项来挂/usr目录。重启之后确认一切正常,就可以将/usr2删除了。

这件事折腾我两天,起因是在家里用firefox 1.0.7无论如何也打不开我的一篇blog,总是显示空白页。运行df命令后发现根目录所在分区没有空间了,以为找到原因,就开始执行上述操作。这是我第一次做这样的事,在这之前对文件系统、设备以及mount都不是非常了解,经过这次尝试,总算有了点概念。可惜空白页还是空白页,我还尝试用wget将那篇blog抓下来,用firefox打开,正常显示!可直接输入url就是不行,没办法,只好将blog的标题更改为Emacs versus Perl,而不是原来的"Emacs vs Perl",从而改变了HTML文件名,然后可以正常显示了。

两个问题最终都解决了,可还是有点郁闷,一天不求甚解两次!:-(

一月 16, 2006

Emacs versus Perl

savannah前不久将CVS匿名访问方式从ext改为pserver,这真是个好消息,因为我终于可以隔着公司的防火墙更新Emacs了。

同时还学了一招——“如何在命令行上更改cvs root”,其中的奥妙就在于Perl-i选项。我原来也做过同样的事情,不过是用Emacs,一个同事虽然是用Perl,不过他写了一个脚本来完成这件事。现在看看当初的帖子,实在汗颜!

今年打算重点写Emacs Lisp程序,上周刚刚将一个Perl程序用Emacs Lisp重写,起因是原来的Perl脚本找不到了:-(,当然也因为要处理的事情比较特殊,要将一种文本格式转换成另一种,然后插入到另一个文件的某个特定位置。当初写的Perl脚本虽然加快了格式转换的过程,但仍然要做一些打开文件,以及复制粘贴的工作。而执行用Emacs Lisp写成的命令则完全不需要在编辑器与命令行之间切换,也不用复制粘贴。当然,打开源文件和目的文件仍然是需要的。关键是在执行命令前要将目的文件所在buffer里的光标定位到要插入文本的位置,然后切换到源文件所在buffer,选定要转换的文本,再执行命令,该命令会提示用户输入一个目标buffer,最后它将转换过的文本插入到目标buffer。

EmacsPerl虽然功能上有重叠,但是只有针对不同任务选择适当的工具,才能达到事半功倍的效果。

一月 10, 2006

Lazy Programmer

Philipp Lenssen说好的程序员既懒又呆,所以我将自己的blog起名为“懒惰的程序员”,以勉励自己。

不过,我有一半是真懒,负面的、贬义的那种。脑子里有很多想法,可就是懒得动手,就拿写这篇blog来说,刚才坐在电脑前发了5分钟呆,犹豫着是不是马上就写。我对自己这个恶习早已深恶痛绝,可改起来还真不容易,所以,为了防止刚刚制订的工作方针流于形式,就打印一份简要的条目,挂在公司座位的正对面,时刻提醒自己。

至少从目前来看,这种方法还算奏效,好几次想把工作拖到第二天再做,抬头看见对面“墨迹未干”的誓言,自己都不好意思了,赶紧行动,毕竟不想这么快就自己打自己耳光吧。:-)

一月 09, 2006

Top 5 Milestones in 2006

和去年这个时候相比,今年更原意展望未来,而不是回顾过去,看起来2005年过得比较颓废。:-(

昨天已经定了2006年的工作方针,今天再写一些具体的目标,希望2006年不要再虚度美好的时光。

  1. 熟练使用Emacs,能够用Emacs Lisp开发一定规模的工具。2005年在Emacs上就没有什么进步,今年要全面掌握Emacs的使用,尤其要做到"Thinking in Emacs",摒弃陋习。另外,到年底时,使用Emacs Lisp的熟练程度要达到我现在使用Perl的水平。
  2. 熟练使用CppUnit,熟练编写测试用例,并开发一个类似于JUnitPerf的插件,或者直接移植过来。
  3. 开发我的网站,以内容为主,技术为辅。翻译OddMuse手册,介绍GraphVizEmacs。开发一个工具将我的del.icio.us定期备份到我的网站上。开发一个工具将我的网站备份到本地。
  4. 开发一个Firefox扩展,方便地从我的del.icio.us里定位tag,查找链接。
  5. 在内容逐渐充实之后,开始有计划、有策略地推销我的网站。

一月 08, 2006

Top 5 Principles in 2006

回顾过去,展望未来。下面是我为2006年制定的原则,指导我在新一年的工作和学习。数字越小,优先级越高。

  1. 多做事,少说话。2005年我说了很多话,以改变从前沉默寡言的形象。但是如果在新的一年继续这样说下去,就成祥林嫂了。所以,话说过了,做事也要跟上。如写一个工具,根据每日工作记录,自动生成月度工作总结。
  2. 多编码,少学习。不是不学习了,而是要学以致用。写一些能够提高工作效率的工具。如用Emacs Lisp写一些代码生成工具和Refactoring工具。
  3. 多记录,少浏览。筛选已经订阅的feed,去芜取精,把时间留给那些值得读的东西上。当然更重要的是记录,充实自己的网站。如写一些系列文章介绍GraphVizEmacs
  4. 多用库、框架和API,少学语言。由于过于重视语言,而忽视了对库、框架和API的学习,使我很难写出具有一定规模的工具。2006年我要学会开发Firefox扩展。
  5. 多看代码,少看书籍。现在的我有点像庖丁解牛里那个月月换刀的屠户。光有好工具是不够的,还要充分了解要处理的对象。说来惭愧,已经好久没有看过我们项目的代码了,工作完全局限在自己熟悉的那块。

一月 07, 2006

Top 5 New in 2005

2005年,我尝试了好多新东西,收获颇丰,希望明年能充分发挥这些工具的作用。

  1. DreamHost.com购买了域名WangLiangHome.org和空间。虽然是年末才发生的事,但却是我这一年做出的最重大的决定,希望我能够借助这个平台做出一些成绩。
  2. 与Web 2.0第一次亲密接触。我不是Web 2.0的狂热者,像大名鼎鼎的Flickr就没尝试过。但是,Del.icio.us, Bloglines, FeedBurner对我的影响是相当大的,它们彻底改变了我使用互联网的方式,极大地拓宽了我的视野。
  3. 我先是在公司的电脑上安装了OddMuse,然后又把它装到了我的网站上。其实早就知道wiki了,原来只是浏览一些wiki网站,今年是我第一次自己安装并使用。wiki组织、发布信息的方式让我很震撼,由此我也对Ward Cunningham更加地崇拜。
  4. 现在起,谈论TDD(Test-Driven Development)就不算纸上谈兵,因为我已经开始使用CppUnit。说实话,我恨它,因为它增大了我的工作强度,没有“偷懒”的机会了。:-)
  5. 摒弃IE,使用Firefox。在我看来,Firefox已经不仅仅是浏览器了,就像Emacs不仅仅是个编辑器。

一月 06, 2006

No Running

绕着公司大楼跑步时被保安制止,还要我出示胸卡。看来下午跑步的计划只能安排在马路上了,但愿不会连出门都不让。

紫竹这边的CS(Corporate Service)比较冷漠,而且条条框框更加多,这也不行那也不行,也不知道谁才是公司的主人。大楼还没有完全弄好就让搬进来办公,毒气吸了几个星期,本来就已一肚子怨气。

有些心灰意冷,工作都提不起精神。最近看德鲁克的书《21世纪的管理挑战》,其中说到现在的普遍现象是人的工作寿命往往要比他所工作过的公司的寿命长,一个成功的公司的平均寿命也只有30年,而一个知识工作者的工作年限可能达到50年。但是很少有人意识到这一点,更少有人根据这个情况规划职业。看来我也该把事业发展的重点放在公司之外了。

一月 05, 2006

More Disk and Bandwidth from DreamHost

DreamHost刚刚免费将所有虚拟主机用户的空间扩大4倍,带宽扩大8倍,而且每周增加量也相应增加。我现在的空间是20G,带宽是1T=1000G!

看来天上掉好东西也不是没有可能,虽然不是馅饼,也不是林妹妹!:-)

Peter Drucker

元旦3天在杭州过的,2号那天逛了书店,买了几本Peter Ferdinand Drucker(1909年11月19日-2005年11月11日)的著作,以缅怀这位“大师中的大师”。

早些时候注意到彼得●德鲁克逝世的消息,但过后就忘了,毕竟不是一个行业,更没读过他的著作。这次逛书店时,进门就发现一张小桌上全是他的著作,还包括一本传记。挑了其中五本买下,花了200元。心里挺佩服杭州新华书店的这种做法,也挺佩服机械工业出版社,这些书全是他们出的,而且中英结合,给予读者选择的自由。

一月 01, 2006

Blog Debut

2006年,我将把blog存在自己的空间上,但仍使用Blogger.com作为前端。而http://feeds.feedburner.com/casper也会指向这里,http://netcasper.blogspot.com/将不再更新。

转换的原因是希望大家不仅可以在RSS阅读器里看到我的文章,也可以连接到我的网站上。为了方便查看FeedBurner里面的统计数据,所有的blog均采用英文标题,直到FeedBurner提供中文支持。

希望大家继续关注我的blog!