在我們開(kāi)始之前先做一下后勤工作……這本書(shū)假定你可以舒服的編寫(xiě) Ruby 代碼窥摄。如果不是這種情況励负,不用擔(dān)心……有很多書(shū)和代碼可以幫助你捶牢。你只要知道,這里有一些主題會(huì)深入一些更復(fù)雜的話題比如 Ruby 加載模式和命名空間遗淳。
就我個(gè)人而言,通過(guò)例子學(xué)習(xí)是最好的學(xué)習(xí)方式心傀。我發(fā)現(xiàn)的最有價(jià)值的書(shū)和文章都會(huì)在涉及到一個(gè)話題后立刻展示真正的代碼洲脂。我會(huì)在適當(dāng)?shù)那闆r下也這樣做。我也會(huì)不留余力的從流行的 Ruby gems 中對(duì)比和高亮代碼只要這是有意義的剧包。我所希望的是這些 gems 可以給你提供些靈感并且最后展示給你看如何讓你的想法可以被轉(zhuǎn)化成可以工作的 Ruby gems恐锦。
讓我們以這種方式開(kāi)始吧……
什么是一個(gè) gem?
一個(gè) Ruby gem 是一個(gè)可以復(fù)用的打包好的 Ruby 應(yīng)用程序或者類(lèi)庫(kù),它專注于特定的功能疆液。Ruby gems 可以做很多事情比如和 Twitter 交互一铅,構(gòu)建 web 應(yīng)用程序,或者管理后臺(tái)任務(wù)堕油,等等潘飘。
Rubygems.org 是一個(gè)被社區(qū)認(rèn)可的 Ruby gems 的托管站點(diǎn)。如果你用 Rails 工作過(guò)掉缺,你很可能用過(guò) bundle install
命令來(lái)安裝在一個(gè) Gemfile
列表中 gems卜录。在大多數(shù)情況下,它們是從 Rubygems.org 被下載和安裝的眶明。
對(duì)于 Ruby 來(lái)說(shuō)很幸運(yùn)的是艰毒,它的開(kāi)源社區(qū)是強(qiáng)而廣泛的。對(duì)于一個(gè)普通的應(yīng)用需要的一個(gè)小功能很少會(huì)不能找到已有的 gem 去引用搜囱。然而丑瞧,不要因?yàn)檫@種情況阻礙了你構(gòu)建下一個(gè)偉大的 gem。
為什么構(gòu)建一個(gè) gem?
拿 Twitter 來(lái)舉例……如果我們寫(xiě)了 3 個(gè)不同的應(yīng)用都需要發(fā)一條推文作為一個(gè)用戶行為的結(jié)果蜀肘,把那些發(fā)送推文的代碼寫(xiě)在 3 個(gè)不同的地方是很操蛋的绊汹。即使只寫(xiě)一次然后復(fù)制/粘貼到每個(gè)應(yīng)用中也是很容易出錯(cuò)的。提取這些代碼到一個(gè)新的 gem 是一件一勞永逸的事情扮宠。用這種方法西乖,我們的應(yīng)用會(huì)得到同一組方法和功能。但是不要擔(dān)心坛增,這個(gè) Twitter 的 gem 已經(jīng)被寫(xiě)好了获雕,所以我們又少做了一件事!
一種更加復(fù)雜的情況牽涉到把一個(gè)龐大的應(yīng)用拆分為微服務(wù)(由更小的致力于特定的功能的應(yīng)用組成)。我們可以考慮這樣做如果我們的應(yīng)用程序變得龐大并且獨(dú)立的組件開(kāi)始變得越來(lái)越復(fù)雜轿偎。服務(wù)的基本原則和管理超出了本書(shū)的范圍典鸡,但是我想說(shuō)被廓,還有一些其他理由讓我們從我們的應(yīng)用程序中提取代碼到 gems 中坏晦。
我寫(xiě)了關(guān)于在我的應(yīng)用中最流行的 ruby gems,再次看看這個(gè)列表, 我從這些 gems 的中得到的好處是巨大的。這是為什么使用 rails 構(gòu)建 web 應(yīng)用能讓你快速迭代一個(gè)原因昆婿。
根據(jù) Rubygems.org 的數(shù)據(jù), 從 2009年7月開(kāi)始已經(jīng)有 66,783個(gè) gems 被創(chuàng)建了球碉,一共被下載了幾乎 24 億次。有大量的下載和大量的 gems仓蛆!開(kāi)源世界是對(duì)于 Ruby gems 和你的 ruby 應(yīng)用程序都是一個(gè)很好的地方睁冬。花一些時(shí)間來(lái)簡(jiǎn)化你的應(yīng)用并且讓其他人能從你的的代碼中獲益看疙,通過(guò)創(chuàng)建一個(gè)開(kāi)源的 Ruby gem豆拨。
公開(kāi)或私有?
我們將要構(gòu)建的 Ruby gem (作為本書(shū)的一部分) 是開(kāi)源的。然而能庆,正如上面提到的施禾,有些情況下把一個(gè)大的應(yīng)用拆分成小的 gems 是一個(gè)好主意,在這種情況下搁胆,把這些小的 gem 作為你組織的私有 gem 是完全合理的弥搞。Github 使得創(chuàng)建私有代碼倉(cāng)庫(kù)很簡(jiǎn)單所以你的代碼是被保護(hù)的。
(好的)例子是很難的
很難去創(chuàng)建一個(gè)不無(wú)聊并且有價(jià)值的例子渠旁。那我們?cè)搫?chuàng)建什么呢攀例?!顾腊?粤铭!
這本書(shū)的第一個(gè)部分將會(huì)專注于一個(gè)簡(jiǎn)單的 Ruby gem,它不會(huì)比決定文件結(jié)構(gòu)和加載依賴更有趣杂靶。雖然這不會(huì)是你見(jiàn)過(guò)的最復(fù)雜的 ruby 代碼承耿,但我希望這個(gè)例子會(huì)足夠用來(lái)展示從開(kāi)始到完成一個(gè) Ruby gem 的構(gòu)建的必備步驟。
MegaLotto
我們會(huì)從一個(gè)創(chuàng)建隨機(jī)彩票號(hào)碼的叫做 MegaLotto
的 gem 開(kāi)始伪煤。
MegaLotto
有兩個(gè)特性:
- 它返回了一個(gè)包含 5 個(gè) integer 的數(shù)組
- 數(shù)組的每個(gè)元素必須是一個(gè) 0 到 60 之間的隨機(jī)數(shù)(不包含 0 和 60 )
這里是兩個(gè)符合要求的例子:
[23, 22, 3, 7, 16]
[13, 20, 26, 1, 9]
接下來(lái)的章節(jié)的重點(diǎn)將會(huì)是我們構(gòu)建一個(gè) Ruby gem 的結(jié)構(gòu)和步驟加袋,和有少量 gem 自己的功能。
總結(jié)
希望我們現(xiàn)在構(gòu)建一個(gè) Ruby gem 的原因和我們這樣做能得到的好處是很清楚的抱既。
Stephan Hagemann 在 MountainWest RubyConf 的一個(gè)演講叫做 Component-based Architectures in Ruby and Rails职烧。這是我所見(jiàn)過(guò)的最好的關(guān)于在你已有的應(yīng)用中提取類(lèi)庫(kù)的演講。Stephan 的演講從為什么你應(yīng)該要從一個(gè) Rails 應(yīng)用程序中提取代碼到你這樣做會(huì)需要的特定方法和步驟都有涉及防泵。我強(qiáng)烈建議你觀看這個(gè)視頻如果你從事大型 Rails 應(yīng)用的開(kāi)發(fā)蚀之。
如果和我一樣,你大概已經(jīng)在想了捷泞,『好了足删,快讓我們看看代碼!』锁右。你是對(duì)的……下一章將會(huì)討論一個(gè) gem 的結(jié)構(gòu)然后我們會(huì)開(kāi)始我們的杰作 —— MegaLotto失受!