星期日, 五月 25, 2008

突然发现“行路难”里有“弹剑作歌”几个字

当时想到用“弹剑而歌”几个字做博客的名字,是因为看一个电视节目,说古人造剑可以发出铿铿的悠远的声音,是因为当时铸造技术比较成熟了,可以将剑身和剑柄铸造在一起,所以声音传播没有阻隔,故能悠远而轻扬。刚才却突然发现李白在一首《行路难》里面有“弹剑作歌”几个字!

行路难

李 白

大道如青天,我独不得出。
羞逐长安社中儿,赤鸡白雉赌梨栗。
弹剑作歌奏苦声,曳裾王门不称情。
淮阴市井笑韩信,汉朝公卿忌贾生。
君不见昔时燕家重郭隗,拥篲折节无嫌猜。
剧辛乐毅感恩分,输肝剖胆效英才。
昭王白骨萦蔓草,谁人更扫黄金台?
行路难,归去来!

不过我心中的形象却不是“奏苦歌”,而是那种提三尺剑,边走边唱的高亢,是“永远自由自我,永远高唱我歌”的潇洒,是“仰天长笑出门去,我辈岂是蓬蒿人”的豪迈和决绝。

风雨如磐暗故园

住处没有电视机,平时也是个心无旁骛不怎么关心时事政治的人,所以网上的新闻看得也少,而且因为刚刚入职需要尽快融入环境,又接手了项目和临时的事情,这样手头的事情也多了,最近心中的思虑其实也颇多的,对地震的事情,虽然也捐了几百大圆,但一直都没有多少感性的认识,每天就是上下班,沉浸在自己不断演进的设想中,虽然 19 号也默哀过了,但心中的触动其实只怕也有限。

昨天从网侠会回来,倒头先睡了两个小时,起来还是觉得有些头痛,不想写东西了,想想上上网吧,看看与地震相关的新闻,那些照片、那些报导这才触动内心感性的东西,查了查伤亡人数,与非典和 98 年洪水对比了一下,发现确实相当很严重,因为这两次印象还是蛮深刻的。今天也看了很久,最新报导说下午青川又有6.4级的余震。不禁想起鲁迅的诗:

灯下漫笔

灵台无计逃神矢,
风雨如磐暗故园。
寄意寒星荃不察,
我以我血荐轩辕。

虽然表面上是温和内敛的人,但实际上却自知内心的刚硬火烈、狂放不羁,今天去理发,老板说我头发硬、头发硬的人心也硬,想想可能也说得不差,但到底硬在什么地方呢?我想也许还是那种不达目的不罢休的二杆子倔劲吧。其实又何尝不曾多次感动、流泪和痛哭呢,只是决不愿示于人前。当自己还是一个倍感绝望的少年的时候,第一次听到黄家驹的歌,我曾经哭泣;《牛虻》曾经使我痛哭;《肖申克的救赎》和《闻香识女人》也曾令我数次感动;常读历史,每每掩卷,常常感慨,有时也会觉得眼角湿润;读林达的《近看美国》的时候也是;在上海的第一个夜晚,何尝不曾绝望;在百阿培训的时候,听讲马云的创业史以及听马云版的《在路上》的时候,我都是躲在角落里抹眼角... 而今天,我觉得,鼻子发酸。

这个民族实在是多灾多难,真的不知道还能坚持多少次?这振聋发聩的响动,不知道能惊醒多少人,能否激起某种精神和信念?或者最终我们只是回到老路上,继续浑浑噩噩的过日子?我们还剩多少血性?我们还剩下多少理想?

不敢说能够“血荐轩辕”,不敢说像于谦那样“风孰于高”,但至少应该“血仍未冷”。我想我现在能做的也就是把手头的这些想法尽力去实现,而现在对我来说也正是这样一个关键时期。本来第一天上岗的时候开周例会,说有个 trouble shooting 的脚本项目,我本来对编程设计、系统架构这块就比较感兴趣,就说我来做吧。因为以前也想到过能否把 trouble shooting 做得像 xUnit 那样,所以这次就正好利用这个机会,建立了这样一个框架,将实际的 Check Points 放到框架下,只要返回结果就可以了,这样就利于将来的扩展,而且可以不仅仅使用 Python,将也可以使用 Shell/Perl 甚至 C 语言来写检查点。

写出来,在上周六加班的时候实际上部署了一次,当然还是有很多问题。而之前,冯大师也表示出兴趣,说能否和监控结合起来,包括和监控负责人和主管这些人讨论下来,甚至希望能够将现在的 Nagios 系统替换掉,因为其性能和可维护性太差。

所以上周又赶了一下具体的需求,以及结合我以前已经产生的设想、在最近 Intel 交流的时候产生的一些新的设想都加进去,实际上在考虑整合的分布式管理系统架构了。当然,事情只能一步步做,饭只能一口口吃,必须把目标步子定得小有点,这样成功的希望才更大。

所以,最近就是要把这个 SaUnit 项目完成,包括新版本的框架,和所有现在需要有的、至少在 Trouble Shooting 上的检查点,我还希望能够乘此把 caxes 的 Tree/Table 完成并集成进去,实际上这周基本上已经完成了 Tree 的重构,去掉了 treedict 这个多余的设计并重新选择数据结构后,发现效率提高了 150 倍!这个要在下个月中旬之前完成,必须考虑到各种困难,还要保证所有的测试能够通过,所以其实时间也应该是挺紧张的。

不管怎么样,我觉得我找到了这样一个可以施展拳脚的地方,一个可能实现自己理想的机会,我知道,我心中的激情仍然没有熄灭,包括昨天在网侠会,虽有有些东西听的也是一头雾水,但毕竟还是能获得新的想法和灵感,甚至可以说是更宏大的设计。虽然这些年也走了很多弯路,也发生过动摇,但最终的抉择还是把我带到了这里——历史决定了我们是谁,我们在其中的幸运和遭遇以及做出的选择,决定了我们今天是怎样的人!不是吗?

吟唱李白的那首行路难吧:
金樽清酒斗十千, 玉盘珍羞直万钱。
停杯投箸不能食, 拔剑四顾心茫然。
欲渡黄河冰塞川, 将登太行雪满山。
闲来垂钓碧溪上, 忽复乘舟梦日边。
行路难,行路难, 多歧路,今安在?
长风破浪会有时, 直挂云帆济沧海。

星期四, 五月 22, 2008

Python 从生成器 "return" 而不是 "StopIteration"

在 ulfs/caxes 项目中的 tree.py 的 __revision__ = 268 版本中,我打算将 __traverse__() 方法做改进,以前返回一个 treedict,所以需要使用 tuple 作为其 pathseq,但现在打算完全取消 treedict,这样用 list 作为 pathseq 要合理得多,此时 __traverse__() 应该作为 generator 不断 yield 数据。

一开始编码如下:
 def __traverse__(self)
"""...
Comments
...
"""
id_self = id(self)
if self.__id_visited.has_key(id_self): return {}
# To avoid cyclic link problem!
Tree.__id_visited[id_self] = None
pathseq = self.__path_stack
yield pathseq, self
...
然后我在 Python 中尝试导入 tree 模块:
>>> import tree
Traceback (most recent call last):
File "", line 1, in
File "tree.py", line 399
yield pathseq, self
SyntaxError: 'return' with argument inside generator
这个错误实际上就是由于上面使用了 return,对 iterator/generator 来说,必须使用 StopIteration 异常处理来终止!
 def __traverse__(self):
id_self = id(self)
if self.__id_visited.has_key(id_self):
# return {}
raise StopIteration
# To avoid cyclic link problem!
Tree.__id_visited[id_self] = None
pathseq = self.__path_stack
yield pathseq, self
......

Python 迭代器和递归调用

如果不使用 for 循环,则只能返回第一次的数据!
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

def iter(x=0):
if x < 100:
yield x * x
for y in iter(x + 1): yield y

for y in iter(): print y