What have you found for these years?

2008-07-23

影響 ruby 最深遠的 ruby program

先說 ruby. 基本上,我覺得除了一些雜七雜八的缺陷外,
ruby 幾乎沒什麼可以挑剔的了。我最不滿意的,大概是
有些情況下 consistency 不太夠。

像是我最近常幹這個錯事:

case obj.class
when String; 'String'
when Array; 'Array'
end


很抱歉,這個結果是 nil, 因為 case 的判斷是用 ===,
不是用 ==. ok, 這有什麼問題?問題在 String === String 是 false.
任何 class 都是 false!!!

因為 Class#=== rhs 的意思其實是 rhs.kind_of? lhs
也就是,上面的程式要把 .class 去掉,意思就對了。

老實講這個問題曾經讓我追蹤很久過,而且最後覺得是 ruby 壞掉了。
才忽然想起來,case 裡好像是有設計成可以判斷 kind_of? 喔...

對我來說,這也是個天大的陷阱啊!!
總之就是像這樣的例外其實還不少...
不過在讀過不少 Matz 的文字之後,
我覺得 Matz 確實都有他的考量在,
並不只是單純覺得這樣看起來不錯就這樣做了。

所以有些時候,我覺得真的可以相信一下 ruby 的設計理念。

bug 和 1.9 的延遲就不多說了,這不太是語言上的問題。
我也沒寫 c extension, 內部程式寫得好不好,也無從置喙。

*

第一名當然是 rubygems 了。基本上這是一套我用過最好的
package management. 其次可能是 macports.

rubygems 厲害的地方在於:

1. 你可以安裝任意版本的 gem (gem install -v GEMNAME)
2. 不只是安裝,runtime 也能任意 require 選擇的版本!
3. command shortcut 很方便 (gem up)
4. 搭配 rubyforge, deployment 很方便
5. 不只是 rubyforge, 使用 --source 指定其他 server
6. 可以把上面的 --source 寫入預設 server 清單 (gem sources)
7. 漂亮的目錄結構,不像 perl/python 都散落一地
8. 族繁我懶得備載

雖然他也是有幾個重大缺點:

1. 早期的版本,如果太久沒更新 gem 的話...
在你下次更新,就等著把系統資源耗盡(CPU+MEM) @@
很多人碰過這個問題,我也碰過...
幸好現在這大麻煩已經修掉了。我不知道為什麼當初這樣寫...
可能覺得每個人都會一直在 update 吧?

2. 我從來就沒搞清楚 list, search, query, 這幾個到底有啥差?
好吧,這可能不能算「重大」缺點...

總之,ruby 能這麼方便,rubygems 絕對是最重要的功臣。
1.9 也包在 standard library 裡面了。

*

第二名我想給 rake. Rakefile 寫起來之容易,
一瞬間就大家都在用,而且用過的也都說好 XD
也被拿來說是 DSL 的成功典範。

而且我還常常想把他拿來當作一般 library 使用...
因為他有一些檔名處理的功能,很方便。
當然自己寫不是不行,問題是他先寫好了嘛...

缺點大概是給參數的方式讓人不是很習慣吧?

> rake app:test zzz=xxx

取得則是:

> ENV['zzz'] # => 'xxx'

我比較希望是:

> rake app:test -t --zzz=xxx

取得則是:

> ARGV # => ['app:test', '-t', '--zzz=xxx']

不過很不幸的是如果後面不是寫成 = 的形式,
arguments 會被 rake 吃掉,然後告訴你:

> /opt/local/bin/rake: invalid option -- t

rake 也是被 1.9 直接收入 standard library 了。
之前 ruby-core 上還有人抗議哩。
說其他 automation tool 都被扼殺了。
不過,應該 95% 以上的人都在用 rake 吧?
至於 rubygems 大概是 99.9% ...

*

第三名大概是 rails 吧。
雖然我覺得他有很多地方的寫法很不好,
但不可否認,他影響非常深遠,而且也有不少有趣的東西。
像是 Symbol#to_proc, 如果我沒搞錯的話,
就是出自 activesupport 的。後來才被 facets 接收,
進而被 ruby 1.9 接收。(同時也被 backport 至 1.8.7)

這是最主要的例子,其他... 我不確定還有沒有。
總之 ruby-core 多多少少會受其影響,就更別提其他 library 了。
花花綠綠,如同雨後春筍一般,因為 rails 的 release 而
開始開發的東西,多如... 螞蟻?

再說,寫起小東西,rails 確實很方便。不以非常嚴厲的眼光去看的話,
rails 也算是 web framework 的佼佼者之一,也有不少 clone...

open source 社群就是要這樣才會興盛啊 ~~~
就像是拋磚引玉一樣,更何況 rails 並不單只是磚。

*

第四名就很難講了。
也許我會說是 rubinius 的 sub-project, rubyspec.

ruby 要標準化應該是完全不可能,因為他的 semantics 實在太複雜了。
更何況他自己本身的 spec, 很多都模糊不清,細節也不斷在改變。
這造成了非常多的麻煩。developer 碰到奇怪的問題可能還是小事,
最嚴重的問題是,讓其他 ruby implementation 無所適從。
接著就會有許許多多的 compatibility issue 出現。

君不見 jruby 剛開始與 mri (matz's ruby implementation) 的
相容性有多差?1.0 時問題還數之不盡!後來修掉幾百還幾千個
compatibility issue? 忘記了,總之真的非常多。

看他一直跑不過我自己的 test case, 後來也就懶得繼續追蹤了。
我才沒寫幾百行就有問題...

rubyspec 促進了 ruby 標準的建立。雖然以 test case 來做的方式
不是很好,之前裡面也有不少 offending test case XD
像是針對 erb 產生出來的 ruby code 做測試,這就有一點太超過了。

不過這也說明著,c/c++ 這種很多很明顯就是 compiler issue,
但是 dynamic 如 ruby, compile-time or runtime,
internal or external, 很多都是無法界定的。
總不成整個 standard library 都用 c 寫吧?
這樣又會失去很多彈性,也會讓 interpreter/compiler 變得
過於複雜。

這也是其難以制定標準的原因之一。
不過至少 rubyspec 促使大家重視這種問題,這樣也許也足夠了?
像是之前也看過不少奇怪的問題,在 rubyspec 出來前,
行為幾乎可以說是毫無界定... 被測出來怪怪的,才被拿出來討論。
而後再把行為修改到比較合理的狀況。

spec 制定者都要想一些很刁鑽的怪問題。(可能很多人會想說神經病)
之前在看 comp.std.c++ 也是,一堆我想都沒想過的詭異問題...
open-std 上的 paper 也是,考量之多,一般 programmer 難以想像。
不過我是覺得這些都很重要,因為沒有人會知道誰會不會碰到各種
古怪的問題。其實這也有點機率的味道,像是,60 億人總有人會碰到這種事。

想這種問題,也促進自己寫出更完備,沒有 bug 的程式...

*

第五名,我要睡了 ><
超過預定時間好幾個小時..........

2 retries:

Plumm said...

看看能不能弄一個 case==
讓它用 == 來判斷 :QQ

godfat 真常 said...

這恐怕要改到 ruby-core 裡面去了
畢竟 case 不是 method

Post a Comment

All texts are licensed under CC Attribution 3.0