小松鼠嚇了一跳,有了魔法眼鏡後,這世界看起來完全不一樣了

2008年3月18日 星期二

那一棒的鋒情

六局下半,兩人出局,一壘有人,一比零,我們還落後一分。

時間是 2007年 12月 3日,中華隊在亞錦賽對上日本,爭取僅有的一張奧運門票。

日本的投手是王牌達比修有。

這時,輪到陳金鋒上場打擊。他在義大利世錦賽拿到全壘打王,已經是十年前的事了。

就像很多其他人一樣,我也在電視前觀看這場比賽。而那種既期待又怕受傷害的感覺又再度出現。期待陳金鋒再度成為救世主,但也很害怕他被三振或接殺。

和很多人一樣,我也有很長的一段日子,窩在廉價租來的小房間,吃的是僅能果腹的食物。那段時間,陳金鋒也在美國職棒大小聯盟間載浮載沉,雖然沉的時候要比浮的時候多些。小聯盟的待遇並不好,但那時早已是國民英雄的他,卻甘之如飴。

和很多人一樣,我時常會注意他的新聞,有時是好消息,其他時候則不是。每當發現他又沒打擊機會甚至又回 3A,雖然不見得完全理性,但常常會埋怨道奇總教練崔西有眼不識英雄,不多給一點機會。

但不管是好新聞還是壞新聞,和很多人一樣,總是期待多看到他的消息。因為只要看到他的出現,再爛的租屋與食物都不算什麼了。他讓我們回想起付出這一切的理由,讓我們記起自己的夢。而每個人的夢想都和他想進入大聯盟的夢想一樣重要。

未來就像投手投出的下一球,你無法預測會是什麼球路。但反正球來就打!也許我們不知道球會怎麼來,可是只要陳金鋒上場,我們永遠知道球要往哪裡去。

所以陳金鋒上大聯盟的時間,我們去道奇看球的頻率就會增加,希望能剛好看到他上場。雖然我們並沒有抱太大希望,因為你也知道,他上場的次數並不多。但還真有那麼一次,我們碰到了。八局上半,陳金鋒上場守右外野。雖然看得有點心驚膽跳,但這次他的守備稱職。九局下道奇進攻,還落後一分,終於快要輪到陳金鋒打擊了。一人出局,一壘有人,打擊的是來自韓國的崔熙燮,陳金鋒在旁邊暖身。我們的劇本當然是崔熙燮上壘後,陳金鋒至少擊出個打點甚至再見全壘打。如果崔熙燮不幸出局,那就是典型的陳金鋒時刻,也該是時候讓道奇的球迷見識救世主的風采了!

全壘打果然出現了,不過是由崔熙燮打出。全場球迷的歡呼雷動。這些歡呼聲裡面,有不少是韓國球迷發出的吧?不知道他們有多高興。我們心裡都默默這樣想。

2005年,我的生活條件變好了不少,而陳金鋒也終於回到台灣家人的身邊快樂的打棒球了。經過七年的辛苦,他終究還是沒能站穩大聯盟。十年前他拿到全壘打王的那屆世錦賽,他在預賽裡創出連四場五隻全壘打的新紀錄。但中華隊預賽就被淘汰,僅得第十三名,有史以來最慘的成績。似乎默默告訴我們這位國民英雄的人生將有帶著悲劇色彩的一面。回到台灣打職棒固然快樂,但缺少了美國職棒激烈的競爭,他對快速球勢必會生疏許多。

事實上,2006年亞洲職棒大賽,面對達比修有的快速球,他吞下 2K。大家都在想,如果他繼續留在美國,結果是否會不一樣?也因此,當陳金鋒上場時,以往只有單純的期待與相信,現在慢慢參雜了一份擔憂。擔憂的感覺慢慢變強,強到甚至某一部份的我,希望他能保送上壘或隨便打個鳥安吧。與其說是不想見到救世主的形象被破壞,不如說不想看到夢想在現實殘酷下幻滅。

回到六局下半。陳金鋒慢慢站上打擊區。和道奇球場那次一樣,壘上有人,兩人出局,落後一分。不同的是,這次,他等到救世主時刻了。問題是,對方的投手可是曾讓他吞下 2K 的達比修有。一年不見,年輕的達比修有正逐漸往頂峰邁進,年輕帥氣的他,來台時成了小女生追逐的偶像。而陳金鋒呢?

然後,我看到他的眼神。突然之間,我有種無法形容的感覺。硬要形容,就像是那種宣稱世界末日的瘋狂預言家附身一樣那種感覺。只不過,這次瘋狂預言家喊的是救世主降臨。不是那種又期待又怕受傷害的感覺,也不是過去那種單純的期待與希望,而是「一定」。他一定會打出全壘打。不是期待或相信,而是絕對的知道。幾球糾纏之後,那個瘋子叫的只是越來越大聲,果然:

球飛出去了,球飛出去了!兩分砲,我們反而領先了。這時候的心情,我想,如果你那時也有看到,你也同樣感受到了。

當然,既然你有看到,你也知道後來發生了什麼事。最後,我們10:2 慘敗。最後幾局,許多球迷都不忍卒睹。那張奧運門票,最後也讓日本拿去了。

時間拉到 2008 年八搶三奧運資格賽,中加之戰,八局下半,四比二我們還落後兩分,兩人出局,一二壘有人,輪到打擊的是有小陳金鋒之稱的羅國輝。

這是我們最後一次爭取奧運門票的機會。陳金鋒因為受傷,沒有參加。沒有陳金峰的中華隊,是一支年輕的充滿新血的球隊。前三場我們三連勝,不過,硬仗從這場才真正開始。事實上呢,因為加拿大比較強,我們鎖定的其實是下一場的澳洲隊。這隻年輕的隊伍,能夠緊咬著強隊加拿大不放,已經讓人對他另眼相看了。

同樣的救世主時刻,但場上的不是陳金鋒。我對羅國輝並沒有特別的期待。不要誤會,我知道他很強,也非常期待並且希望他能打出全壘打。只是相比之下,這個期待並不特別而已。畢竟,他不是陳金鋒。

直到看到他的眼神,我才知道我有多錯。因為,那是陳金鋒對上達比修有的眼神。我很確定,因為那個瘋狂預言家又跑出來了。「一定,這是一定救世主降臨的時刻!」

接下來發生的事情,就看影片吧:

果然,救世主降臨,球四平八穩飛出去了!5:4,我們領先了。只要再撐一個半局,我們就贏了!不過,就像中日戰一樣,我們又被逆轉了。但是這次不一樣,他們與加拿大奮戰到延長加賽,才以 6:5 一分之差飲恨。

他們說,要帶陳金鋒賢拜到北京。

當陳金鋒回來打球的時候,我們說能夠打過大聯盟,夢想已經達成。我們說,追夢本身就是一切。我們說,夠了,你付出夠多了,該是回到家人身邊快樂打球的時候了。但是,說沒有完全遺憾是騙人的。

直到今天,我才了解之前的想法有多膚淺。夢想從來就沒有遺憾。陳金鋒的夢想已經傳承到這隻年輕的隊伍上了。

這幾年,陳金鋒已經用他的行動,默默的影響了所有人,他的隊友們,學弟們,球迷們,所有台灣人。甚至也許,他的對手們。這個勇敢追夢的精神,已經深深地影響了每一個人。夢想的傳承,從來沒有斷過,從紅葉開始到世界盃、亞洲杯、奧運各項國際賽,從成棒到職棒的分分合合、從往日職發展到往美國發展,這個傳承,一代接著一代,從來沒有斷過,而且逐漸茁壯。我們見證了陳金鋒將他隊棒球的體悟,傳遞給年輕的後輩。

如果說奧運象徵人類對於夢想的追求,那麼,他們帶去的不是陳金鋒,而是我們每一個人。

每一天,你在自己的崗位上辛勤奮戰,為了自己的夢想而努力,就像所有的上班族、業務員、學生、生意人、工人或者任一個人。早上出門途中,買早餐時和老闆娘互道謝謝。謝謝你買我的早餐。謝謝你努力做的早餐。謝謝早上的太陽。謝謝中華隊。今天也要努力喔。

藉由短暫的接觸,堅守崗位、努力追夢的信念。在每個人之間傳遞著。

所以我們不會忘記,球要往哪裡去。

有一隻球隊,數十年來,將我們的夢想代代傳承。有人叫他中華隊,有人叫他台灣隊,但從沒有人為此爭執。因為我們知道,我們支持的是同一隊。

有一個人,在自己崗位堅持,埋頭耕耘。他是陳金鋒,他也是你我。也許講到台灣之光,人們第一個想到的不是他。但我們知道,只要我們都努力照亮身旁的人,台灣就會閃亮耀眼。

延伸閱讀:遷徙的冠羽: 帶陳金鋒去北京

2008年3月5日 星期三

中文程式語言

每次一提到中文程式語言,常常會看到人批評「中文程式語言」不實用,浪費時間。

「程式裡面用的英文很簡單啦,不會造成困擾」

「打英文還比較快」

沒有錯,對「一般人」來說,也許的確不實用。

大部分的人都把自己當成是「一般人」(常常也沒有錯),但是忽略掉自己前面和後面都還有人。

同樣的那群「一般人」,他們會偏好中文的文件和軟體,也會感謝翻譯成中文化的作者。

如果單從我自己的角度來看,中文化根本沒必要,浪費時間。因為「文件中用的英文很簡單,不會造成困擾」、「直接看英文還比較快」。

而我的英文還很爛呢。

如果連我都覺得中文化翻譯都是沒有意義、浪費時間,更何況是對英文程度正常的人來說?

還好,不是每個人都只從自己的需求來看世界。

那些想磨練英文而翻譯的人不談(其實翻譯品質堪慮),中文化的工作者本身往往不需要這些中文化文件和軟體的,他們是為了別人而做的。

「一般人」的確需要感謝那些翻譯者,感謝他們不像「一般人」一樣,只因自己不需要,就認為浪費時間、不實用。

很明顯的,發展中文程式語言的人,也不是因為自己需要才發展的。

前幾天到我家裝潢,弄電路、音響的人,有些甚至連 In, Out 這麼簡單的字, 都不是很確定。以前當兵的同袍,英文的程度也是遠低於我的預料。他們才是真正的一般人。

但我認為他們其實都很聰明,如果有適當的環境,如果程式可以用中文寫,他們也許就能學會寫程式。

這是我關心中文程式語言的初衷。即使遠在當兵之前,我還過份高估一般人英文程度的時候也一樣。

因為我知道,這個世界很大,有很多不同的人,很多狀況會出乎我預料。

比方,我也實在不知道 OOPS 開放課程計畫的中文翻譯到底要給誰看。

我無法想像能有多少人能學習高等課程,卻看不懂英文。我無法想像有人需要這套計畫。

我反而能想像那種因為是中文,而望文生義誤解的人(推翻相對論,滿口量子能量場、證明尺規三分角的那類人)。

但同樣的,我知道世界上的人有千百種,如果要我下注,我還是會站在有人需要那邊。

2008年3月3日 星期一

James Dean 語錄

(照片來源: wikipedia)
James Dean,雖然過世很久,但是作為美國通俗文化的一個象徵,還是大家耳熟能詳的名字。
我當然也知道這位二十四歲早逝的電影明星,不過也只是模模糊糊的知道而已。
直到後來,發現了一些他的語錄,才驚訝到注意到一個不到二十四歲的人居然說過這麼深刻的話。
後來想想,大概很多是電影台詞吧?不過,還是不減這些名言的有趣性。

  • "Dream as if you'll live forever, live as if you'll die today.” 這句是他的經典名句。
  • “Only the Gentle are truly strong.” 厲害的人,都很溫柔呢。James Dean 的名句比漫畫早得多。
  • “I want to be a Texan 24 hours a day”
  • “Rebel Without a Cause.” 應該是電影片名
  • “Eternity? ... That is one hell of a movie.”
  • "There is no way to be truly great in this world. We are all impaled on the crook of conditioning. A fish that is in the water has no choice that he is. Genius would have it that we swim in sand. We are fish and we drown."
  • "And my heart just did a flip-flop over that."

2008年3月2日 星期日

用 30 行 ruby 寫俄羅斯方塊

學一種程式語言,第一步是先跟著 Tutorial 走一遍。
然後,找到參考手冊,因為,這是你的救生圈。像是 Python 的文件就寫得相當清楚。
所以,我無法理解那些在網路上問一些官方文件就有答案的問題的人。如果一個人看不懂文件上那麼清楚的文字,那表示他閱讀能力有問題。那他又怎麼能夠讀懂網友回答的文字?
現在學 ruby,文件風格和 python 有很大不同,但是也非常清楚有用。
當然,光是這樣還不夠,還要真的寫幾個程式才能算數。
至於要寫哪些程式呢?每個人都有自己喜好。就我來說,以前,每學一種 GUI framework 或者語言,我會寫一個 Ansi Terminal Emulator。更早一點,還沒有 GUI 的時候,碰到新的系統,會寫個簡單的畫圖程式和簡單的中文系統 Viewer。
這有點像是一種儀式,如同成年禮一樣,你學程式語言的成年禮。寫完這一個中小型的計畫,就能說自己會一種語言了。
不過我學 Python 的時候,倒是沒有什麼成年禮。因為 Python 實在太好學了,差不多是看到就會了。勉強要說的話,就是之前那個 Alpha-Beta Search 系統。
但這也就是為什麼我 Python 的程式設計能力不太紮實的緣故。後來用 Python 寫了一些短的的俄羅斯方塊,才體會到這點。
所以,現在我學 Ruby 時,也打算把俄羅斯方塊當成是成年禮的一部分。以下就是用 ruby 寫的 29 行俄羅斯方塊。


require "tk"
W,H,Blk=40,40,{0xf=>"red",0x2e=>"#0f0",0x27=>"blue",0x47=>"#ff0",
0x66=>"#0ff",0xC6=>"#38f",0x6C=>"#f0f", 0=>"#000"}
Bkeys=Blk.keys.select{|x| x!=0}
new_piece= proc{ proc{|pc| {:a=>(0..16).select{|i|(pc>>i)&1>0}.map!{|i|
[(i>>2)+1,i&3]},:i=>3,:j=> -2,:c=>pc}}.call Bkeys[rand(Bkeys.length)]}
def collide(na,ni,nj)
na.map {|n| true if @board[nj+n[1]][ni+n[0]]!=0}.include? true
end
def redraw
@canvas.delete "all"
@board.each_with_index{|b,j| b.each_with_index {|c,i|
TkcRectangle.new(@canvas, i*W, j*H, i*W+W,j*H+H,
'fill'=>Blk[@p[:a].include?([i-@p[:i],j-@p[:j]])? @p[:c]: c])}}
end
@score, @bw, @bh, @p = 0, 10, 20, new_piece.call
@board=Array.new(@bh+3){|j| j!=@bh ? [0]*@bw+[15]*3:[15]*(@bw+2)+[0]}
(@canvas=TkCanvas.new :width=>@bw*W,:height=>@bh*H).pack
TkRoot.new.bind("Any-Key") { |e| na,ni,nj=@p[:a],@p[:i],@p[:j]
ni+= e.keysym=="Left" ? -1:(e.keysym=="Right" ? 1:0)
na=na.map{|n| [n[1],3-n[0]]} if e.keysym=="Up"
nj+=1 if e.keysym=="Down"
@p[:a],@p[:i],@p[:j]=na,ni,nj unless collide na,ni,nj
redraw}
TkTimer.new(200,-1){|e| !(collide(@p[:a],@p[:i],@p[:j]+1) or !(@p[:j]+=1)) or
proc{ @p[:a].each{|n| @board[n[1]+@p[:j]][n[0]+@p[:i]]=@p[:c]}
@board=@board.inject([]){|a,l| l.include?(0)? a+[l]:[[0]*@bw+[15]*3]+a}
@p[:j]<0 ? exit : @p=new_piece.call}.call
redraw}.start(0).mainloop
這個比 python 的 tk 版要短,不過可讀性差多了。
原來寫的可讀性比較高,最開始甚至還有定義一組 class,不過行數大約是五十行。
後來不用 class,就變成 40行以內,然後再進一步犧牲一點可讀性,就降到了三十行以內。
ruby 高手可能可以找到不少以上程式碼的可笑錯誤吧!
ruby 和 python 的比較一直是個熱門話題,不過呢,我得先要等我更了解一點 ruby 再說。

2008年2月14日 星期四

充氣娃娃之戀


最近一個月看了不少電影,
  • 色戒
  • 練習曲
  • 變形金剛
  • 男孩不壞 Superbad
  • C+偵探
  • There will be blood
  • The Eye: 美國版見鬼,本來要看 Cloverfield,但是 imdb 的時間表不太正確。
  • 蜂電影 Bee Movie
  • 誰才是導演 Clash of Egos/Sprængfarlig bombe : 丹麥片
  • 充氣娃娃之戀 Lars and the Real Girl
很多是飛機上看的,其中 Superbad 和誰才是導演都很不錯,色戒、練習曲、變形金剛都不用說。There will be blood 評價兩極化,看之前要有心理準備,C+偵探的風格還挺有趣的, The Eye 放鬆心情看,還是能達到娛樂效果。
不過這裡我要推薦的是充氣娃娃之戀。
影片簡介很簡單:害羞內向的 Lars,向他的哥哥和大嫂介紹他的女友。見面之後,發現居然是一個充氣娃娃。而 Lars 卻完全把充氣娃娃當成真人一樣對待(把她當人看)。在這個純樸的小鎮上,大家會怎麼看待這件事情呢?
光是看到片名,大家聯想到的可能是下面這段(娶充氣娃娃為妻的日本人)

即使不往變態片的方向想,想像的大概也是類似男孩不壞、四十歲處男、Knocked up 或美國派這樣的內容。
實際上,這部片子是極為溫馨的片子,是一部傑作。我不是說美國派、四十歲處男、男孩不壞
這些不好,只是說這部片子走的是更加內斂而溫情的路線。
裡面不乏簡單卻又讓人驚豔、發人深省的台詞和情節,像是冰凍的腳(你要看電影)的那一段話,或者是把(相對)正常的嗜好 action figure、絨毛玩具、寵物等等,拿來和把充氣娃娃當真人相比。
某些的情境下,人們不也嚐嚐把感情寄託在寵物、玩偶上嗎?將他們擬人化嗎?不也常常對虛擬的小說、電影人物,媒體塑造出的偶像賦予情感嗎?我們有什麼理由說 Lars 是不正常的?
(雖然說也有很多文化會把迷戀偶像、漫畫、action figures視為怪胎,也有 crazy cat lady一詞)但電影裡更多的是沒有文字的場景,一個眼神、一個表情、一個動作,傳達出許多只能意會的感動和情感。
所以不要被片名誤導了,這是一部相當好的電影。

有關修改周蟒的動機

gasolin 在他的回應中,有一段話:
但同時警覺到: 讓人寧願自己修改而不是發個 patch 給我們,也表示周蟒還有不足之處。
讓我覺得我需要稍微解釋一下我修改的動機。
拿 zhpy 當 MagicCodec 的一個模組,是目的。看到 zhpy 包含 pyparsing 之後,我就知道我必須要修改一下才能使用,因為 PyLua 裡面已經用到了 Ply ,再包一個 pyparsing 太重複了。
而且我知道 zhpy 的功能只需要 tokenizing 就夠了。所以一開始就準備把 pyparsing 去掉,換成標準的 regex。
當然將命令列換成 MagicCodec 是初衷,既然現在要刪掉 pyparsing,就順便把一些不要的功能刪除,然後把 Interactive interpreter 換成 PyOS_Readline hook , exception handling 換成 hook。
看了程式碼後,因為身為一個設計師的天性,自然會有很多意見,包含風格和功能性。其中風格主要是一些程式碼審美觀(程式碼重複),而功能性包括zh_exec 的功能性, 還有翻譯字典的編碼(utf8 str or unicode)。
有關風格和功能性的選擇上,帶有主觀的設計選擇成分,雖然說(依照定義)我認為我的選擇較好,但是我也可以理解別種想法的可能性。我也有一些「不好」的選擇,包含會用一些 python 2.5 才有的語法,在 python 3k 不向下相容之際,有點尷尬。但我的辯解是 python 3k 可以直接用中文當變數名稱(*), zhpy 在 python 3k 下本來功能性就有不同的目的,所以也不算太尷尬。
那為什麼不考慮 python 2.4 2.3 的使用者呢?一來 python 2.5/2.6 的壽命會很久(因為沒有 2.7),二來我認為除非付出現在 30 倍以上的努力(推廣和設計),中文程式設計不會真的有實際用途。在推出試驗機型 prototype 時,這些不是我需要關心的事情。
gasolin 寫 zhpy 的目的和想法顯然不同。而我的目標對象根本就不是 end user,這也就是我連 distutil setup 都不提供的原因。因為整個設計取向不同,所以我拿原來的 zhpy code 來 refactoring,而不是 直接利用。因此也談不上 patch 原來的 zhpy 的 code,因為修改後的 zhpy 和原來的 zhpy 本來就是為了不同目的的產物。
我要設計一台飛天車,拿一台量產的車子當基礎來修改,但不代表原來的量產車也要加上翅膀。


(*)理論上, python 2.x 不能用中文變數名,不完全算是 python 的問題,而是中文字到底哪些算是字母的問題。 python 2.x 是用 isalpha 和 isalnum 來判斷合法名稱的,而這些和 LC_CTYPE 有關。理論上,可以修改 glibc locale 設定的 LC_CTYPE或者用 vista 的 custom locale builder 來告訴 python 哪些算是「字母」。

2008年2月7日 星期四

Python MagicCodec 0.1(更新到 0.11)

這個是基於 PEP 263 弄的 python meta programming 小玩意。
包含兩個神奇編碼 zhpy 跟 PyLua。 MagicCodec 0.1 Download
(*更新 0.11)
安裝玩 MagicCodec 之後,下面這段會變成完全合法的 Python 程式
# encoding: zhpy_utf8
吼叫="啦啦啦"
印出 吼叫
執行 '印出 "再%s一次"%吼叫'
這個也是
# encoding: lua
i=10
function run(func) repeat func() until i==0 end
run(function () print("Hello!",i) i=i-1 end)
直接用 python 執行,或者用滑鼠點 xxx.py 就可以執行了。
MagicCodec 裡面包含的 zhpy 基於 zhpy 1.4,但是大量修改過了(幾乎全部改掉)。
有幾個修改的重點:
  1. 直接用 re 來做 tokenizer。殺雞不用牛刀,原來的 zhpy 用 pyparsing 。雖然說 pyparsing 提供很方便的功能來分解字串,但是類似的功能直接參考 python bnf 用 re.sub 來做,反而更簡單。
  2. 改掉許多重複的程式碼。原來 zhpy 有非常多的程式碼,重複好幾次。tw 的了一個函數,cn 的又寫一個函數。這樣維護起來很難。
  3. zh_exec 的功能和 exec 不同。我將他改成了比較符合原來 exec 行為的程式碼。改完後,原來的 zhpy_commandline 會爛掉,但實際上,會爛掉反而是 exec 的正確行為。
  4. 「執行 」我還是直接翻成 「exec zhpy.dec <<」,因為 zh_exec 是函數,跟指令 exec 的語法不同。
  5. type(x) == type("") 這類, 改成 isinstance(x,str)
另外一個重要的不同是改以 source code encoding 導向,將 zhpy 視為 python 的一個 codec,而不是另外一個 python 的實做。所以有許多差異。
  1. 用 MagicCodec 取代 zhpy_commandline,因為直接用 python xxx.py 就能執行了。而不用 zhpy xxx.py
  2. 用 excepthook 取代 try_run。
  3. 另外增加 PyOS_Readline hook,這樣 python 的命令列可以直接變成 zhpy 的命令列。所以取代原來執行 zhpy ,改用執行 python ,然後你 import zhpy.hooks;zhpy.hooks.setup_all() 就可以直接執行中文的程式碼。
  4. python win 也行,用前面的 zhpy.hooks 就可以了。
  5. idle 不行。因為 idel 是分離式的。如果你在 MagicCodec 的 __init__ 或者執行 idle 前執行 zhpy.hooks.setup_all(),就可以。
  6. idle 編輯器讀取 zhpy codec 的程式碼會解碼。所以會有問題。(所以 MagicCodec 也不永遠比較好)
  7. import 比較單純。原來 zhpy import hook 就不錯了。但是現在更好,因為不用修改, python 就能直接 import zhpy 的 module。原因很簡單,因為有 MagicCodec 之後的 zhpy 程式碼是合法的 python 程式碼。
但是還是有很多東西不行。
像是
# encoding: zhpy_utf8
吼叫="啦啦啦"
印出 吼叫
執行 '印出 "再%(吼叫)s一次"%locals()'
就會失敗,這個不難解決,只要用另外的 hook 包住 locals, globals, setattr, getattr 等。__dict__比較麻煩一點,這個是 mataclass 可以hook的。


更新(2008-02-28):由於網友 tocer 的反應,找到了好幾個 bug。
我其實有好幾個 Ubuntu 的機器,不過之前太懶,所以都沒有測試過。
所以雖然有考慮到, Linux 應該會有的狀況,不過都是用「想的」。
我們都知道,寫程式這樣是不行的。一測之下,果然 bug 連連。
第一個問題是好幾個檔案的權限設定有問題,windows 下還好, linux 下一般使用者就出問題了。
第二點主要是 encoded file 的問題。裡面幾個 return,雖然我是用很保守的 hook 法,但至少要傳回一些東西吧!另外還有一個語意上面的 bug 就是了。就是因為我要用保守的方式,只 hook,真正原始 file 形式的 sys.stdout/sys.stderr。所以語意應該是
if type(f) !=file: return f
才對,而不是
if type(f)==file: return
至於為什麼原來在 cygwin 上可以跑?我就不清楚了。現在剛好我手上又變成沒有 cygwin 機器了。搞不好 0.11 在 cygwin 上變成不能跑。
不過不管怎麼樣,這裡只是 display hook 上面的問題而已。最多就是顯示出問題。

Ubuntu 上建議使用有顯示 UTF8 能力的 Terminal。

最後,Ubuntu 上錯誤顯示會失效,因為 sys.excepthook 已經被其他 package 搶走了。我用很保守的策略來搶 excepthook,所以別人搶了,我就讓給別人。當然,你可以設定為強迫 excepthook(看程式碼)。
所以 hello.py 的錯誤展示有點多餘。

另外,還有一點小改動就是不再像 0.1 那樣 hook zhpy_codec 的 decode,只 hook streamReader。


更新(2008-03-01):
zhpy 1.5 已經出了,我雖然還沒有仔細看,不過應該有一些有趣的進展。