電影流水帳(2008/05/27~2008/05/30)

一次五片,算是五連發嗎?

  • 10,000 BC(IMDB, Wikipedia),中譯:史前一萬年。電影就是電影,如果你認為這部片子會好好考據史實的話,最好不要對這部片子抱太高期望,因為它並不是你所想像中的片子,反而比較像是類似魔蠍大帝那種歷史傳奇的故事。女主角Camilla Belle蠻正的,不錯 (Google圖片搜索)。
  • National Treasure: Book of Secrets(IMDB, Wikipedia,中譯:國家寶藏2-古籍秘辛。上一集的班底再次出動,這次還扯上英國女王、美國總統,不過我覺得這次比較沒什麼感覺~普普通通。
  • The Lizzie McGuire Movie(IMDB, Wikipedia),中譯:莉琪的異想世界。學生片,少女畢業,畢業旅行去羅馬,在羅馬發生了不少事。女主角Hilary Duff在 Disney 頻道蠻紅的樣子,所以才有一系列的電影。
  • Next(IMDB, Wikipedia),中譯:關鍵下一秒。拍攝的手法讓你不知道從什麼時候開始是主角的預測,原來從邂逅發生感情開始,就是主角對未來的預測了,搞半天,其實只需要看一半就行了,因為之後的事情都沒發生過。
  • The secret of Loch Ness,中譯:尼斯湖水怪傳說。這部片子我在IMDBWikipedia上都找不到,只能列上Yahoo! Movie的連結。最初我本來以為是The Water Horse: Legend of the Deep這部片,後來才發現不是。網路上影評兩極化,主要原因是預告片剪得很爛,幾乎把劇情全部剪進去了。不過我是還蠻喜歡這部片子的,很適合小朋友看,很溫馨。

Boo(15)-內建函數:容器操作

join()、map()、array()、matrix()、iterator()、enumerate()、range()、reversed()、zip()、cat()
這一類的函式還…蠻多的,大多都與 python 相容。
join(),把 Enumerator 裡面每個元素轉成字串,最後串成一個字串傳回。你也可以加上第二個引數,他會自動幫你加上,例如:join( [1,2,3,4,5], “:” ) 會得到 “1:2:3:4:5” 的字串。
map(),對 Enumerator 裡面每個元素施行指定的函式。
array(),傳入一個 Enumerator 回傳一個陣列。
matrix(),建立多維陣列。
iterator(),取得物件的 IEnumerable 介面,如果物件沒有 IEnumerable 介面,但有繼承 TextReader 的話,則改用 TextReaderEnumerator.lines() 取得 IEnumerable。這個函數在內部非常頻繁地被這裡提到的其他函數使用到。
enumerate(),先取得物件的 IEnumerable 介面,然後傳回類似 (index, value ) 的 Enumerator,舉例來說,List( enumerate( [ “a”, “b”, “c”, “d” ] ) ) 的結果會是:[(0, ‘a’), (1, ‘b’), (2, ‘c’), (3, ‘d’)]。
range() 很容易理解,傳入數值,會回傳有循序數值的 Enumerator,你也可以傳入起始與結束的數值或是傳入起始、結束與遞增數。
reversed(),將 Enumerator 裡面的元素以相反順序擺放,內部是使用 ReversedListEnumerator 類別來完成這件事情。
zip(),傳入多個 Enumerator,它會把每個 Enumerator 的第 0 個元素放到一起、第 1 個元素放到一起…以此類推,最後再傳回一個 Enumerator。這個函數看例子會比較容易了解,array(zip([‘a’,’b’,’c’],[4,5,6],[‘aa’,’bb’,’cc’])) 的結果會是 ((‘a’, 4, ‘aa’), (‘b’, 5, ‘bb’), (‘c’, 6, ‘cc’))。老實說,我還沒想到要怎麼用…
cat(),跟 join 有點像,不過不會傳回字串,而是把傳入的 Enumerator 串接起來成一個 Enumerator 再傳回。
這裡有的函數我沒舉例,要看例子的話,可以參考Boo Primer中文版對內建函數的說明

LXPanel Plugin in Managed code?

看到 Fred 寫的Fred’s blog: 讓我們輕鬆自在設計自己的 LXPanel Plugin,心想,應該也可以用 mono c#、boo 等來寫吧~
於是想到gimp-sharp,這個 library 讓你可以使用 c#、vb.net、boo 寫給 gimp 使用的 plugin,下載來看以後,真是令人驚訝~
原來 gimp 是使用外部執行的方式去呼叫這些 plugin,而這些 plugin 以收取參數與呼叫 gimp library 的方式來與 gimp 主體進行溝通。
那麼這樣,似乎就行不通了。一般 C/C++ plugin 的處理方式,都是以 dl_xxxx 系列函數來開啟 plugin(.so) 進行操作,對於 managed code 來說,assembly(.dll)並沒有開放這些介面。
從 C/C++ 呼叫 Managed code 是可行的,目前只適用於 Mono,請參閱這裡:Embedding Mono
這裡有幾個範例,應該是夠用了。
看起來如果要作 Plugin 給 lxpanel 用的話,還是得用 C 寫一個 Plugin,然後這個 Plugin 負責載入 mono 的 assembly,再把必要的資訊傳進去給 managed code。
有可能作成 chain-loader 的形式,由這個 Plugin 再去把其他用 Managed code 做的 Plugin 載入嗎??
恐怕還是得再看 lxpanel 內部如何用 plugin 才能決定。

LXDE in Ubuntu

如果你想在 Ubuntu 裡試試 LXDE 的話,加入這個軟體來源:

deb http://ppa.launchpad.net/lxde/ubuntu/ hardy main universe multiverse restricted

,然後安裝 lxde、lxsession 即可 (sudo apt-get install lxde lxsession)。接下來登出,將作業階段選為 LXDE,再登入即可。
LXDE 的確速度蠻快的,不過,不能瀏覽網路上的芳鄰,這實在是讓我無法下定決心跳槽啊…
補充:啊,LXDE 的下載網頁也有提到一個來源:

deb http://people.linux.org.tw/~pcman/ubuntu/ ./ 

電影流水帳(2008/05/21~2008/05/26)

六月底前要來統計一下,看看上半年看了多少部電影。

  • Jade Soturi(IMDB, Wikipedia),中譯:玉戰士。故事穿梭在現代與過去之間,簡單的說,在前世由於主角為了愛情,不想得到永恆的生命,選擇了不殺死魔鬼,將其封印,讓自身掉入輪迴。到了現代,由於文物的出土,導致事情必須作一個了結,在主角鍛造 Sampo 的過程中,慢慢回想起過去,也知道自己必須要面對並解決。整體來說,感覺上很艱澀,不容易懂,藝術的氣息很重。除此之外,張靜初(IMDB)真的蠻正的(照片)。
  • TEETH(IMDB, Wikipedia)。這部片子台灣有上嗎?從故事內容看起來,並不是台灣片商會喜歡的類型,但在中文維基百科上能找到它的蹤跡:小心有牙,或許是影展片也不一定。我是第一次聽到有牙陰道的傳說,片中的女主角由於受限於教規的約束,從來沒有探索過自己的身體,也以為自己與其他女孩一樣,因緣際會被男友強上,才發現自己與其他女孩的不同,被強暴、自己的身體與其他人不同、母親過世,一連串的事件讓女孩心理產生了變化,看到最後居然會想莞爾一笑,果然不負黑色喜劇之名。

Boo(14)-內建函數:輸入與輸入

print、gets、prompt

print 就是調用 Console.WriteLine() 而已,官方建議使用 print macro,而不要使用這個函數。
gets 從標準輸入取得一個字串,實際上就是調用 Console.ReadLine()。
prompt 是 Console.ReadLine() + Console.Write() 的組合技,在印出你給的提示訊息之後,會接著從標準輸入取得字串。

從標準輸入取得字串的意思就是,畫面會停住,等你輸入字元,直到你按下 Enter 之後,才把你輸入的字元放到字串裡傳回。

print("Hello")
s = gets()
print s
s = prompt("Please input something:")
print s

當然,除了這些函數以外,你還是可以直接使用 .NET Framework 裡的 System.IO 來處理。

Boo(13)-內建函數:shell 類

shell()、shellp()、shellm()
顧名思義,就是執行外部的程式。

shell() 會等待外部程式執行完成以後,回傳一個字串,字串裡是執行的結果。
shellp() 不會等待外部程式執行完成,會直接回傳 Process 物件,事實上,shell() 也呼叫了這個函數,只是 shell() 拿到 Process 物件以後,利用 Process.StandardOutput() 去讀取執行結果,並使用 Process.WaitForExit() 等待程序執行完成。
shellm() 也是執行外部程式,但這個外部程式必須是 Managed,也就是 .NET 應用程式。老實說,看了 boo 源碼以後,我不是很懂。源碼裡面是建立一個新的 AppDomain,載入指定的程式,然後找到 EntryPoint 並執行。我猜想,這樣的作法主要用來避免再次建立新程序、啟動 CLR,在 CPU、記憶體使用上會比較有效率。如果你的外部程式正好也是 .NET 應用程式的話,就用 shellm(),我想會比較好。

input = shell( "booc.exe", "" )

電影流水帳(2008/05/14~2008/05/20)

每年推的片子應該都超過百部吧~假設每部片子都到電影院去看早場,早場票價是200元,那麼這樣的花費就會是 100*200 = 20000 元;看二輪片,而二輪片票價是 110 元兩部片子的話,則是 50*110 = 5500 元;至於 DVD,百視達新片一片 80 元的話,100*80 = 8000 元。無聊的計算?!

  • 明日的記憶。這部片子非常適合作為阿茲海默症的宣導片子,幾乎把所有可能發生的情況都演出來了,很容易讓人理解患病之後,會發生什麼事情。說來,老年痴呆症(阿茲海默症,另類的絕症!)真的是很令人無力啊~我的外公在晚年也罹患了這種疾病,舅舅照顧得很辛苦~在前年的時候,外公走了,從病痛中解脫。嗯嗯,照這樣看來,我也有阿茲海默症的可能性,是不是該及早做好準備呢?
  • 劇場版「NARUTO-ナルト-疾風伝」(Wikipedia),火影忍者-疾風傳。嗯嗯,就是卡通啦,沒什麼特別好說的。

P.S. 印象中二輪片票價是 110 元,我已經有超過五年以上沒去看過了吧,所以這票價是五、六年前的票價。

booc 的 49 道工法

從 Visual Studio debugger 裡面截出來的…想不到編譯需要這麼多步驟…

-		_items	{維度:[64]}	object[]
+		[0]	{Boo.Lang.Parser.BooParsingStep}	object {Boo.Lang.Parser.BooParsingStep}
+		[1]	{Boo.Lang.Compiler.Steps.InitializeTypeSystemServices}	object {Boo.Lang.Compiler.Steps.InitializeTypeSystemServices}
+		[2]	{Boo.Lang.Compiler.Steps.PreErrorChecking}	object {Boo.Lang.Compiler.Steps.PreErrorChecking}
+		[3]	{Boo.Lang.Compiler.Steps.ExpandAstLiterals}	object {Boo.Lang.Compiler.Steps.ExpandAstLiterals}
+		[4]	{Boo.Lang.Compiler.Steps.MergePartialClasses}	object {Boo.Lang.Compiler.Steps.MergePartialClasses}
+		[5]	{Boo.Lang.Compiler.Steps.InitializeNameResolutionService}	object {Boo.Lang.Compiler.Steps.InitializeNameResolutionService}
+		[6]	{Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces}	object {Boo.Lang.Compiler.Steps.IntroduceGlobalNamespaces}
+		[7]	{Boo.Lang.Compiler.Steps.TransformCallableDefinitions}	object {Boo.Lang.Compiler.Steps.TransformCallableDefinitions}
+		[8]	{Boo.Lang.Compiler.Steps.BindTypeDefinitions}	object {Boo.Lang.Compiler.Steps.BindTypeDefinitions}
+		[9]	{Boo.Lang.Compiler.Steps.BindGenericParameters}	object {Boo.Lang.Compiler.Steps.BindGenericParameters}
+		[10]	{Boo.Lang.Compiler.Steps.BindNamespaces}	object {Boo.Lang.Compiler.Steps.BindNamespaces}
+		[11]	{Boo.Lang.Compiler.Steps.BindBaseTypes}	object {Boo.Lang.Compiler.Steps.BindBaseTypes}
+		[12]	{Boo.Lang.Compiler.Steps.BindAndApplyAttributes}	object {Boo.Lang.Compiler.Steps.BindAndApplyAttributes}
+		[13]	{Boo.Lang.Compiler.Steps.ExpandMacros}	object {Boo.Lang.Compiler.Steps.ExpandMacros}
+		[14]	{Boo.Lang.Compiler.Steps.IntroduceModuleClasses}	object {Boo.Lang.Compiler.Steps.IntroduceModuleClasses}
+		[15]	{Boo.Lang.Compiler.Steps.NormalizeStatementModifiers}	object {Boo.Lang.Compiler.Steps.NormalizeStatementModifiers}
+		[16]	{Boo.Lang.Compiler.Steps.NormalizeTypeAndMemberDefinitions}	object {Boo.Lang.Compiler.Steps.NormalizeTypeAndMemberDefinitions}
+		[17]	{Boo.Lang.Compiler.Steps.BindTypeDefinitions}	object {Boo.Lang.Compiler.Steps.BindTypeDefinitions}
+		[18]	{Boo.Lang.Compiler.Steps.BindGenericParameters}	object {Boo.Lang.Compiler.Steps.BindGenericParameters}
+		[19]	{Boo.Lang.Compiler.Steps.BindEnumMembers}	object {Boo.Lang.Compiler.Steps.BindEnumMembers}
+		[20]	{Boo.Lang.Compiler.Steps.BindBaseTypes}	object {Boo.Lang.Compiler.Steps.BindBaseTypes}
+		[21]	{Boo.Lang.Compiler.Steps.BindMethods}	object {Boo.Lang.Compiler.Steps.BindMethods}
+		[22]	{Boo.Lang.Compiler.Steps.ResolveTypeReferences}	object {Boo.Lang.Compiler.Steps.ResolveTypeReferences}
+		[23]	{Boo.Lang.Compiler.Steps.BindTypeMembers}	object {Boo.Lang.Compiler.Steps.BindTypeMembers}
+		[24]	{Boo.Lang.Compiler.Steps.ProcessInheritedAbstractMembers}	object {Boo.Lang.Compiler.Steps.ProcessInheritedAbstractMembers}
+		[25]	{Boo.Lang.Compiler.Steps.CheckMemberNames}	object {Boo.Lang.Compiler.Steps.CheckMemberNames}
+		[26]	{Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping}	object {Boo.Lang.Compiler.Steps.ProcessMethodBodiesWithDuckTyping}
+		[27]	{Boo.Lang.Compiler.Steps.PreProcessExtensionMethods}	object {Boo.Lang.Compiler.Steps.PreProcessExtensionMethods}
+		[28]	{Boo.Lang.Compiler.Steps.UnfoldConstants}	object {Boo.Lang.Compiler.Steps.UnfoldConstants}
+		[29]	{Boo.Lang.Compiler.Steps.OptimizeIterationStatements}	object {Boo.Lang.Compiler.Steps.OptimizeIterationStatements}
+		[30]	{Boo.Lang.Compiler.Steps.BranchChecking}	object {Boo.Lang.Compiler.Steps.BranchChecking}
+		[31]	{Boo.Lang.Compiler.Steps.CheckIdentifiers}	object {Boo.Lang.Compiler.Steps.CheckIdentifiers}
+		[32]	{Boo.Lang.Compiler.Steps.StricterErrorChecking}	object {Boo.Lang.Compiler.Steps.StricterErrorChecking}
+		[33]	{Boo.Lang.Compiler.Steps.CheckAttributesUsage}	object {Boo.Lang.Compiler.Steps.CheckAttributesUsage}
+		[34]	{Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions}	object {Boo.Lang.Compiler.Steps.ExpandDuckTypedExpressions}
+		[35]	{Boo.Lang.Compiler.Steps.ProcessAssignmentsToValueTypeMembers}	object {Boo.Lang.Compiler.Steps.ProcessAssignmentsToValueTypeMembers}
+		[36]	{Boo.Lang.Compiler.Steps.ExpandProperties}	object {Boo.Lang.Compiler.Steps.ExpandProperties}
+		[37]	{Boo.Lang.Compiler.Steps.RemoveDeadCode}	object {Boo.Lang.Compiler.Steps.RemoveDeadCode}
+		[38]	{Boo.Lang.Compiler.Steps.CheckMembersProtectionLevel}	object {Boo.Lang.Compiler.Steps.CheckMembersProtectionLevel}
+		[39]	{Boo.Lang.Compiler.Steps.NormalizeIterationStatements}	object {Boo.Lang.Compiler.Steps.NormalizeIterationStatements}
+		[40]	{Boo.Lang.Compiler.Steps.ProcessSharedLocals}	object {Boo.Lang.Compiler.Steps.ProcessSharedLocals}
+		[41]	{Boo.Lang.Compiler.Steps.ProcessClosures}	object {Boo.Lang.Compiler.Steps.ProcessClosures}
+		[42]	{Boo.Lang.Compiler.Steps.ProcessGenerators}	object {Boo.Lang.Compiler.Steps.ProcessGenerators}
+		[43]	{Boo.Lang.Compiler.Steps.ExpandVarArgsMethodInvocations}	object {Boo.Lang.Compiler.Steps.ExpandVarArgsMethodInvocations}
+		[44]	{Boo.Lang.Compiler.Steps.InjectCallableConversions}	object {Boo.Lang.Compiler.Steps.InjectCallableConversions}
+		[45]	{Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions}	object {Boo.Lang.Compiler.Steps.ImplementICallableOnCallableDefinitions}
+		[46]	{Boo.Lang.Compiler.Steps.CheckNeverUsedMembers}	object {Boo.Lang.Compiler.Steps.CheckNeverUsedMembers}
+		[47]	{Boo.Lang.Compiler.Steps.EmitAssembly}	object {Boo.Lang.Compiler.Steps.EmitAssembly}
+		[48]	{Boo.Lang.Compiler.Steps.SaveAssembly}	object {Boo.Lang.Compiler.Steps.SaveAssembly}

第 0 步由 Boo.Lang.Compiler.Pipelines.Parse (src\Boo.Lang.Compiler\Pipelines\Parse.cs) 加入。
第 1~27 步由 Boo.Lang.Compiler.Pipelines.ResolveExpressions (src\Boo.Lang.Compiler\Pipelines\ResolveExpressions.cs) 加入。
第 28~46 步由 Boo.Lang.Compiler.Pipelines.Compile (src\Boo.Lang.Compiler\Pipelines\Compile.cs)加入。
第 47 步由 Boo.Lang.Compiler.Pipelines.CompileToMemory (src\Boo.Lang.Compiler\Pipelines\CompileToMemory.cs) 加入。
第 48 步由 Boo.Lang.Compiler.Pipelines.CompileToFile (src\Boo.Lang.Compiler\Pipelines\CompileToFile.cs)加入。

這些步驟都是利用繼承的關係建立起來的:CompileToFile -> CompileToMemory -> Compile -> ResolveExpressions -> Parse
只應用了繼承的威力…