為什么說Ruby比Python容易閱讀
這是一篇充滿偏見的語言戰爭文章,是一場無意義的錘子和錘子的比拼。語言的復雜性可以通過選擇語言回避,而問題本身的復雜性是選擇哪個語言都無法回避的。
不屑語言戰爭的人可以輕松無視此文。
1、字符串格式化
Python
在閱讀 Python 字符串格式化的時候,視線先看到字符串的 %s 字樣,但是不知道這指的是什么,然后看后面的變量 k,再接著看第二個 %s ,再看后面的 v 視線必須不停地在字符串和變量之間跳動。
Ruby
而閱讀 Ruby 字符串格式化的時候,看到需要變量的地方,變量就在那里。
順便一說
這種風格的代碼在 Ruby 里面也能用,Ruby 的理念認為解決問題的方法可以不止一種,選擇哪種取決于程序員的喜好。
2、映射(迭代)
這在 Python 中叫做列表解析,不過不管叫什么,實際上這是迭代的一種。
li 是一個 list。閱讀這行代碼的時候,先看到 elem*2,但是不知道 elem 是什么。繼續看,再次看到 elem ,還是不知道是什么。一直看到 in li,奧,原來 elem 是 li 中的元素,對了,剛才對 elem 做了什么來著?
如果一個元素的解析還不太迷惑,繼續看下面這個例子。
請問我應該先看哪個部分。
下面是 Ruby 版。
求 params 的映射(map),其中的元素是原本params里面 k, v 鍵值對組成的字符串,我不確保沒有 Ruby 基礎的人會不會習慣這種 block 語法,但是我可以保證閱讀代碼的時候是從左到右的單一順序。
3、DSL(領域語言)
為了舉一個現實中有代表意義、但是又足夠簡單的例子,我找到了 webpy 和 sinatra,這分別是 Python 和 Ruby 社區熱門的簡潔風格 web 框架。
前置的說明是,webpy,甚至是 Python,都不是一個追求 DSL 的社區。而 Ruby 社區則以 DSL 見長,這樣比較似乎有失公允。但這里可以比較 DSL 的有無對于代碼的可讀性有什么幫助。
webpy 的 hello world
urls = (
'/', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self):
return 'Hello, world!'
if __name__ == "__main__":
app.run()
我對 webpy 原本的 helloworld 做了簡化,以便和 sinatra 比較。
坦率地說,webpy 的 hello world 已經夠簡潔了。相比起 Java EE 和 .net 龐大的 IDE 和那根本不知道拿來做什么的規范,webpy 讓我們回歸了單純,簡約而不簡單。
但是,簡約方面,Ruby 的 DSL 文化更是做到了極致,看 sinatra 的例子
get '/' do
"Hello World!"
end
sinatra 的 DSL 非常簡練,甚至讓人懷疑它是否是一個玩具。或者可以看下 sinatra 的文檔或者用戶列表,現在請先暫且相信,它做的事跟 webpy 沒什么兩樣。
DSL 是語言層面的封裝,把復雜性留在庫的內部,把接口用 DSL 的形式暴露給程序員。這其實跟類和函數方式的 API 沒有什么不同。不過 DSL 會讓人忘記自己正在使用什么語言,Rubyists 的說法是:魔法。
總結
Python 和 Ruby 雖然同為動態語言時代的佼佼者,不過開發和社區風格有很大的不同。這歸根于兩個語言誕生時的理念不同:Python 注重規范化,一個問題只有一個方法,縮進的強制約束,便于多人合作;而 Ruby 注重人性化,便于閱讀,一個問題有幾個方法,過多的魔法需要使用者自己鍛煉駕馭能力。
這樣的結果就是偏重數學,偏重模范化的人喜歡 Python;偏重樂趣,偏重人類語言化的人喜歡 Ruby。