Archive for August, 2007

新生报道

Sunday, August 19th, 2007

这几天又是一年一度的新生报道时间了,学校一下子热闹起来,晚上竟然灯火通明,行政楼外面所有的灯都开起来了。不过我不太喜欢热闹,或者说“不喜欢热闹”。路上到处都是人,人多了其他东西就多了,比如噪音、满地的垃圾、横七竖八的自行车……还有食堂以及各种超市都排着长长的队,一点都没有进去的欲望了。

还有我那把最破的伞,撑起来几乎就是一个骨架,能遮雨的部分不过四分之一,我一直都放在车篓里以备不时之需,也自信天下最没人品的人也不屑去拿那把伞的,也就我有时发颠撑着那把伞洋洋自得罢了。不过这次它真被拿走了,在我车篓里面放了一年了,寿命也算长了吧。看到车篓里面还有一张字条,以为小偷竟然留下借条,仔细一看,原来是XX日租的广告。

唉!总之就是很讨厌,人一多就龙蛇混杂了,特别是报道和毕业的时候经常有各种人混进学校来,反正校门也是大开着。想想实验室那位大哥竟然连本科学位证都被偷走了,真的是很无奈。

Spun down disk properly

Thursday, August 16th, 2007

更新内核到 2.6.22 除了前面提到的 vmnet 编译错误的问题,还在关机的时候多出来了一条警告:

DISK MIGHT NOT BE SPUN DOWN PROPERLY. UPDATE SHUTDOWN UTILITY
For more info, visit http://linux-ata.org/shutdown.html

这是关机的最后一条信息了,一直都没有特别注意,因为信息显示出来紧接着机器就关掉了,不太来得及看清楚。今天特地记下那个链接,去那里看了一下,好像是 SATA 硬盘在关机的时候没有按照“正常”的程序关闭的问题,文中说原因是老式的 shutdown 程序没有提供对新的机制的支持,因此需要升级 shutdown 来解决这个问题。可是网站上并没有提供补丁或者是新版本的 shutdown 下载。

再搜索了一下之后发现另外一个解决办法,就是将 /etc/init.d/halt 脚本里面的参数 "-h" 替换为 "" 。我试了一下,这样确实就不再有那样的警告信息了。

memoize in Ruby

Tuesday, August 14th, 2007

Common Lisp 的经典书《On Lisp》的 5.3 节叫做 Memoizing 。书中讲到了将函数调用的返回值缓存起来的一种技术。这本来是一种非常常见的技术,但是《On Lisp》让我看到了动态语言的精练之处,这样的一种技术被抽象成一个通用的函数,将任意一个函数传入 memoize ,就会得到一个经过包装的函数,并且它已经具备了缓存的能力:

1
2
3
4
5
6
7
8
(defun memoize (fn)
  (let ((cache (make-hash-table :test #'equal)))
    #'(lambda (&rest args)
  (multiple-value-bind (val win) (gethash args cache)
    (if win
        val
        (setf (gethash args cache)
        (apply fn args)))))))

下面是一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CL-USER> (setf (symbol-function 'memoized)
         (memoize #'(lambda (x)
          (sleep 5)
          x)))
#<closure (LAMBDA (&REST ARGS)) {B7B80F5}>
CL-USER> (time (memoized 1))
Evaluation took:
  5.0 seconds of real time
  0.004 seconds of user run time
  0.0 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.
1
CL-USER> (time (memoized 1))
Evaluation took:
  0.0 seconds of real time
  0.0 seconds of user run time
  0.0 seconds of system run time
  0 calls to %EVAL
  0 page faults and
  0 bytes consed.
1
</closure>

Read the rest of this page »

Vmware module vmnet refused to compile under linux 2.6.22

Tuesday, August 14th, 2007

最近升级到了 Linux 2.6.22 的内核,vmware 需要重新编译一下内核模块。不过这次并不那么顺利,安装好内核头文件以后运行 vmware-config.pl ,在编译网络模块的时候出错了。从错误来看应该是内核源代码变动造成的吧,在网上搜索了一下,发现是 Linux 内核里面对 network stack 有很大的改动造成的。并且在这里找到了一个可以下载的 patch 以及打好 patch 的 vmnet.tar 。那里的作者说是在 AMD64 下正常工作的,我使用的是 Vmware 6 ,机器是 IA32 ,我看到回复里面说 IA32 也正常的,于是就下载回来了。

把下载回来的 vmnet.tar 放到 /usr/lib/vmware/modules/source 目录下,然后再运行 vmware-config.pl 就 OK 了。

我把 vmnet.tar 也放到我这里,需要的用户可以直接从我这里下载

Ruby 里的元编程

Sunday, August 12th, 2007

关于元编程

Wikipedia 上关于元编程的定义说元编程就是将程序作为数据进行处理。“用程序来处理程序”,这就是“元”的来源了,这本身是一个容易产生混淆的地方,就像“用语言来描述语言”一样,数学上的许多悖论就来自于此呢。幸好我们用的编程语言比自然语言要简单许多,并且都有严格的定义规范,有兴趣的人可以尝试在自己喜欢的编程语言里面构造一下 “This statement is false” 这个经典悖论。

回到元编程,程序处理程序可以分为“处理其他程序”和“处理自己”,对于前者,有我们熟悉的 lex 和 lacc 作为例子。而对于后者,如果再细分,可以分为“宏扩展”、“源代码生成”以及“运行时动态修改”等几种。

宏扩展从最简单的 C 语言的宏到复杂的 Lisp 的宏系统,甚至 C++ 的“模板元编程”也可以包含在这一类里面,我在这里对它们进行了一些介绍。

源代码生成则主要是利用编程语言的 eval 功能,对生成出来的源代码(除了在 Lisp 这样的语言里面以外,通常是以字符串的方式)进行求值。有一类有趣的程序 quine ,它们运行的结果就是把自己的源代码原封不动地打印出来,通常要证明你精通某一门语言,为它写一个 quine 是绝佳的选择了,这里有我搜集的一些相关资料。

最后是运行时修改,像 Lisp 、Python 以及 Ruby 之类的语言允许在运行时直接修改程序自身的结构,而不用再经过“生成源代码”这一层。当然对源代码进行 eval 的方法也许是最灵活的,但是它的效率却不怎么样,所以相来说并不是特别流行。这里主要介绍的是这种方式的元编程在 Ruby 里面的应用,如果对元编程的其他方面感兴趣,前面的几个链接应该都是很好的去处。

Read the rest of this page »

中文问题

Wednesday, August 8th, 2007

今天收到一封邮件,让我感到很失落。其实是一封道歉信。起因是我在邮件列表里面问了一个问题,而我的邮件用户名称是用的中文,邮件列表里面的一个用户那里无法正常显示中文(应该是字体的问题吧),当然这种乱码看上去很像病毒一类的,被自动标记为垃圾邮件了。后来他发现了这个问题,取消了垃圾邮件的标记,并发来了这封道歉信。

首先我看到国内和国外对待这种小事的区别了。国内的好像多是“不拘小节”吧,而国外的人似乎都挺追求完美的(至少在我所常见到的 IT 这个领域里面是这样的),从国内和国外的各种技术 Blog 以及 Wiki 的排版就能看出这个问题(且不论内容)。其实我那封邮件里面的问题已经在邮件列表里面得到了回答,而那个人还专门发了一封道歉信来说明一个也许是“微不足道”的问题吧。我想,在国内的邮件列表或者论坛里面恐怕是不会见到这种情况的,即使有,估计也是被大家嘲笑的吧(比如,一堆 “ORZ” 跟过来,我对这个特别反感)。

另一方面,我又不得不承认,中文的这种状况——这正是让我感到沮丧的原因了。且不论各种乱七八糟的编码,即使大家都用 UTF-8 ,我想外国人也很少会去装那么大一个中文字体库了吧,当然如果中国够强盛,或者中国的 IT 届够牛的话,肯定会另当别论的了。真是郁闷,中国不乏牛人,可是 IT 届为什么一直就那么浮躁呢?

另外,其实我比较感兴趣的是,他怎么知道他那里的一堆乱码是中文字的? :P

动态语言的尴尬

Monday, August 6th, 2007

一提到动态语言,一般都会想到像 Python、Perl 以及 Ruby 之类的语言了,按照 Wikipedia 上的定义,动态语言是这样的:

Dynamic programming language is a term used broadly in computer science to describe a class of high level programming languages that execute at runtime many common behaviors that other languages might perform during compilation, if at all. These behaviors could include extension of the program, by adding new code, by extending objects and definitions, or by modifying the type system, all during program execution. These behaviors can be emulated in nearly any language of sufficient complexity, but dynamic languages provide direct tools to make use of them.

动态也不是说着玩的,一般 dynamic programming language 都是 dynamic typed ,换句话说:变量无类型,而值有类型。像以下的代码当然是基本要求了:

a = 12;
a = "foo";

当然还有其他动态的地方,比如,如果语言是面向对象的,那么对象的特征甚至类型通常都可以在运行时改变,甚至类也可以多次被“打开”进行修饰和修改,总之就是想怎么变就怎么变,让人写起程序来跟捏泥巴似的,哪儿不像了揉一下重新捏。再换个说法,动态语言之于静态语言,就好像它引入了时间,而不在是静止的了。静态语言编译好之后就是那个样子了,而动态语言得到的东西说不定过一会儿就和刚才不一样了(当然事情不是那么绝对,因为即使是静态语言也可以修改自己的二进制代码,关于这一点,甚至有关系到动态语言的定义的争论)。

然而动态语言这种特性却也有尴尬的一面,因为它让源代码变得“不可信”了。

在开源社区里面有一个普遍的观点:源代码是最好的注释。注释有可能(并且通常是)滞后于源代码,更关键的是,源代码没法骗人,代码怎么写,程序就必然是那个样子的了。而现在到了动态语言里面,这招不好用了,比如,在 Rails 里面,那些 model 通常是一些空类,但是你却看到在其他代码里面调用它们的许多乱七八糟的方法,而且这些方法在父类里面也没有定义:函数就这样凭空造出来了!真神奇!现在什么 grep ,TAGS 通通都不灵了!比如在 Pascal 里面,你可以搜索“function”就得到关于函数定义的语句。而在 Ruby 里面呢?比如,要找函数 foo ,可能可以搜索 def *(self.)?foo ,这是比较常用的定义函数的方法了,用简单的文本搜索工具就可以搜索到。但是定义函数的方法远远不止这一种啊。

Read the rest of this page »

大嗓门

Sunday, August 5th, 2007

有个室友是大嗓门。其实平时也不大嗓门,可是一打起电话来就特别兴奋了,整个就是在吼。好像这样的人也不少吧,大概是这种性格吧,一点也不会在意周围的情况,经常在很安静的书店里面突然听到一个人拿着电话大叫,实在是很厌恶这种人。不过平时也就算了,大半夜也那样打电话,真叫人恼火,可惜不像小时候那样打雷都吵不醒了,正睡得舒服被大嗓门吵醒,真是特别不爽!真想拿个大木棒过去把他敲晕在电话机那里,然后大家都好好睡觉。 :P 可惜我的性格也不怎么好,遇到这种情况总是忍者不说,其实我是非常不爽的,我也不知道自己为什么不说,大概还是不善于交涉吧,毕竟是室友,也不想为了小事把关系搞僵了。 Sigh~~