如何在 Rails 項(xiàng)目中使用 Rubocop 統(tǒng)一程序風(fēng)格?

團(tuán)隊(duì)開(kāi)發(fā)一個(gè)Ruby on Rails項(xiàng)目時(shí),寫程序的風(fēng)格很難統(tǒng)一,不管是從其他語(yǔ)言轉(zhuǎn)行過(guò)來(lái)的老手,或是剛學(xué)習(xí)程序開(kāi)發(fā)的新手,必定和其他團(tuán)隊(duì)成員有習(xí)慣不同的地方。適時(shí)使用像Rubocop這樣的程序評(píng)量工具,會(huì)讓團(tuán)隊(duì)的程序風(fēng)格更趨于統(tǒng)一。
為何要統(tǒng)一程序風(fēng)格?
Rails的設(shè)計(jì)風(fēng)格是「?jìng)鹘y(tǒng)比設(shè)定更重要」,因此長(zhǎng)久下來(lái),Ruby及Rails社群逐漸歸納出一套邏輯,希望在所有開(kāi)發(fā)者都能養(yǎng)成默契,在加入開(kāi)發(fā)各種項(xiàng)目時(shí)不會(huì)難以接軌。這套邏輯是由Bozhidar Batsov首先制定,稱作“Ruby Style Guide“及”Rails Style Guide“。其中包含許多我們不陌生的寫法,例如Ruby 1.9推出的新Hash寫法,將{:foo =>“bar”}精簡(jiǎn)為{ foo:“bar”},諸如此類的規(guī)定,不只讓入門新手有很詳細(xì)的參考,資深的開(kāi)發(fā)者也可以依照這套邏輯來(lái)統(tǒng)一整體團(tuán)隊(duì)的風(fēng)格。
不過(guò),要花時(shí)間檢查所有人的程序有沒(méi)有符合這些規(guī)定,實(shí)在有點(diǎn)浪費(fèi)時(shí)間,身為一個(gè)Ruby程序員,實(shí)在沒(méi)理由不用現(xiàn)成的工具來(lái)完成這件事。這類協(xié)助檢查程序風(fēng)格并點(diǎn)出問(wèn)題的工具稱為「代碼測(cè)評(píng)」,包括Rubocop、Rails best practices、Flog等,從不同角度來(lái)提供我們不同的數(shù)據(jù)。目前開(kāi)源工具中最普遍使用的就是Rubocop。
Rubocop簡(jiǎn)介
Rubocop同樣也是由Batsov這位神人開(kāi)發(fā)者所寫,只要一個(gè)指令,他就會(huì)告訴我們哪邊的代碼有問(wèn)題。他完全依照Ruby Style Guide和Rails Style Guide內(nèi)的風(fēng)格來(lái)檢查,因此只要把兩篇文章讀透了,每當(dāng)產(chǎn)生錯(cuò)誤,基本上也不致于到無(wú)法理解的地步。
最簡(jiǎn)單的使用方法就是在開(kāi)始新Rails項(xiàng)目或其他Ruby項(xiàng)目時(shí),依據(jù)說(shuō)明在根目錄下新增.rubocop.yml檔案,并將所有需要及剃除的檔案列出,接著就像是回家作業(yè)一樣,每次寫完一段程序就執(zhí)行rubocop指令(或是搭配編輯器的整合功能),看是否有需要修改的地方。當(dāng)然,他內(nèi)置有數(shù)百個(gè)檢查項(xiàng)目,剛開(kāi)始使用一定非常不習(xí)慣,例如強(qiáng)迫每個(gè)method要保持在10行之內(nèi)、每個(gè)class要保持在100行以內(nèi),這些對(duì)許多開(kāi)發(fā)者來(lái)說(shuō)都非常頭痛。但只要耐著性子,每一次的修改都會(huì)越來(lái)越熟練,到最后你會(huì)發(fā)現(xiàn)那些標(biāo)準(zhǔn)的風(fēng)格寫法已經(jīng)內(nèi)化,寫出來(lái)的代碼都非常的有質(zhì)量。
如何用于既有項(xiàng)目
當(dāng)然,一般的團(tuán)隊(duì)在初創(chuàng)時(shí)期根本不可能將時(shí)間運(yùn)用在如此奢侈的檢測(cè)視工具上。大部分開(kāi)始使用rubocop的項(xiàng)目都是已經(jīng)有一定迭代的團(tuán)隊(duì),發(fā)現(xiàn)團(tuán)隊(duì)間的代碼風(fēng)格難以統(tǒng)一,不得已才必須開(kāi)始使用的工具,除了推行困難之外,要在短時(shí)間內(nèi)解決所有問(wèn)題難如登天,通常中型項(xiàng)目檢查出來(lái)的問(wèn)題都會(huì)超過(guò)1000個(gè)以上,不安排個(gè)兩三個(gè)月,根本無(wú)法修復(fù)。
最好是在項(xiàng)目根目錄的.rubocop.yml當(dāng)中先將全部的檢查項(xiàng)目關(guān)閉,確認(rèn)無(wú)誤后再逐一解開(kāi),藉由一個(gè)一個(gè)項(xiàng)目的修復(fù),團(tuán)隊(duì)也比較容易培養(yǎng)默契。
這樣一來(lái),團(tuán)隊(duì)可以優(yōu)先處理最容易有bug的問(wèn)題,例如在項(xiàng)目當(dāng)中寫了binding.pry這樣的中斷功能,卻沒(méi)有在推送時(shí)拿掉,這樣讓其他團(tuán)隊(duì)成員接手開(kāi)發(fā)時(shí)發(fā)現(xiàn)服務(wù)器會(huì)在莫名的地方暫停。
整合服務(wù)
Rubocop執(zhí)行非常方便,而在團(tuán)隊(duì)管理上也有非常方便的整合工具。例如為了確保團(tuán)隊(duì)每個(gè)成員都有乖乖使用這個(gè)工具,就可以利用像Code Climate這樣的持續(xù)整合(continuous integration)工具,讓每位成員在將程序推送到Git服務(wù)器(例如GitHub)上時(shí),可以設(shè)定自動(dòng)檢查是否有風(fēng)格問(wèn)題,只要不符合就會(huì)跳出警告,讓所有漏洞無(wú)所遁形。基本上只要連續(xù)出現(xiàn)數(shù)個(gè)錯(cuò)誤,大概就可以判斷這個(gè)成員根本偷懶沒(méi)執(zhí)行這個(gè)工具了!
另一個(gè)很方便的服務(wù)是HoundCI,同樣將程序推送到Git服務(wù)器時(shí),會(huì)自動(dòng)檢查,更神的是會(huì)自動(dòng)送出pull request,用以自動(dòng)修正錯(cuò)誤,這些整合服務(wù)都能在項(xiàng)目管理上加快速度,并且維持程式品質(zhì)的良好。
小結(jié)
在項(xiàng)目中要統(tǒng)一風(fēng)格并非易事,而自己身為開(kāi)發(fā)者要能遵循這些原則也要花上一段時(shí)間。但隨著項(xiàng)目的逐漸擴(kuò)大以及團(tuán)隊(duì)成員的增加,使用這樣的自動(dòng)化工具來(lái)增加管理效率,才是像Matz所說(shuō)”work hard to be lazy“的精神,只要先把原則建立起來(lái),后續(xù)要管理就方便多了!共勉之!
