自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Rails應(yīng)用的助手:Rake背后的故事

開發(fā) 開發(fā)工具
作為一個(gè)Rails的開發(fā)者,你可能很熟悉使用Rake進(jìn)行你的測試。這篇文章中,我們將討論為什么要?jiǎng)?chuàng)建Rake,和他怎么樣幫助我們的Rails應(yīng)用,最好你可以寫自己的Rake。

作為一個(gè)Rails的開發(fā)者,你可能很熟悉使用Rake進(jìn)行你的測試,或者使用Rake db:migrate運(yùn)行你的migrations,但是你真的知道Rake的背后故事嗎?你意識到可以自己寫一個(gè)Rake任務(wù)或者一個(gè)有用的lib嗎?

51CTO推薦專題:Ruby On Rails開發(fā)教程

下面是我們使用Rake任務(wù)的例子:

1、給列表中的用戶發(fā)送郵件

2、每晚數(shù)據(jù)的計(jì)算和報(bào)告

3、過期或重新生成緩存

4、備份數(shù)據(jù)和svn版本

5、運(yùn)行數(shù)據(jù)處理腳本

一、歷史回顧:Make

為了了解Rake的來歷,我們先了解一下Rake的爺爺:Make。讓我們回到那個(gè)代碼塊需要編譯,解釋性語言和iphone還沒出現(xiàn)在地球上的時(shí)代?;氐侥菚r(shí),我們下載的大型程序,還是一堆源代碼和一個(gè)shell腳本。這個(gè)shell腳本包含了所有需要用來compile/link/build的代碼。你需要運(yùn)行“install_me.sh”這個(gè)腳本,每一行代碼將被運(yùn)行(編譯每一行源文件),然后生成一個(gè)你能夠運(yùn)行的文件。

對于大多數(shù)人這樣是不錯(cuò)的,但是對于程序開發(fā)人員卻是一個(gè)不幸。每次你對源代碼進(jìn)行一個(gè)小的改動,并進(jìn)行測試的時(shí)候,你需要回到shell腳本,并重新編譯所有的源代碼,顯然對于大的程序“那是相當(dāng)?shù)?rdquo;耗時(shí)的。

1977年貝爾實(shí)驗(yàn)室的Stuart Feldman創(chuàng)造了“make”。解決了編譯時(shí)間過長的問題。Make用來編譯程序,取得兩方面的進(jìn)步:

[[14049]] 
Stuart Feldman

(1)Make可以發(fā)現(xiàn)哪個(gè)文件在上一次編譯后改動過,根據(jù)這點(diǎn),再次運(yùn)行Make時(shí),僅編譯改動過的文件。這個(gè)很大程序上減少了重新編譯大型程序的時(shí)間。

(2)Make可以進(jìn)行從屬跟蹤。你可以告訴編譯器,源文件A的編譯需要源文件B,源文件B的編譯需要源文件C,所以Make在編譯A時(shí)發(fā)現(xiàn)B沒有編譯,將會先編譯B。

可以這樣定義:Make是一個(gè)可執(zhí)行程序。像ls或dir一樣。讓Make理解如何讓編譯一個(gè)項(xiàng)目,需要?jiǎng)?chuàng)建一個(gè)makefile文件,描述所有的源文件和依賴關(guān)系。makefiles有自己的語法,你不用去了解。

這些年Make出現(xiàn)了其他的變體,并且被其他的語言使用。事實(shí)上,Ruby用戶在Rake出現(xiàn)前也在使用它。但是,Ruby并不需要編譯,我們用它來干嘛?Ruby是一個(gè)解釋性語言,我們不需要編譯它的源代碼,所以Ruby程序員為什么使用它呢?兩個(gè)重要的原因:

(1)創(chuàng)建任務(wù)

在大型的應(yīng)用中,你經(jīng)常編寫腳本,在命令行下運(yùn)行一些任務(wù)。比如清除緩存,維護(hù)任務(wù),或者遷移數(shù)據(jù)庫。你可以寫一個(gè)MakeFile來組織你的任務(wù),而不是寫十個(gè)不相干的腳本(或者一個(gè)復(fù)雜的)。這樣你可以簡單的運(yùn)行:“make stupid”。

(2)從屬任務(wù)跟蹤

當(dāng)你開始寫一些維護(hù)任務(wù)的時(shí)候,可能發(fā)現(xiàn)有些任務(wù)的使用可能有重復(fù)。比如,“migrate”任務(wù)和“schema:dump”都需要鏈接數(shù)據(jù)庫,這樣我可以創(chuàng)建一個(gè)任務(wù)"connect_to_database",使“migrate”和“schema:dump”都依賴于"connect_to_database",這樣下次運(yùn)行“migrate”時(shí),"connect_to_database"會先于“migrate”運(yùn)行。

#p#

二、如何得到Rake

幾年前,Jim Weirich在一個(gè)java項(xiàng)目上使用了Make,他發(fā)現(xiàn)如果在他的Makefile中寫一小段Ruby代碼將會帶來非常大的方便。所以他創(chuàng)建了Rake。

[[14050]] 
Jim Weirich

Jim為Rake創(chuàng)建了任務(wù)功能,附屬關(guān)系跟蹤,甚至創(chuàng)建了時(shí)間段判斷(timestamp recognition),(在上一次編譯的基礎(chǔ)上僅編譯改動的部分),當(dāng)然,對于Ruby,我們并不需要編譯。我很想知道Jim在代碼里做了什么,你也想知道吧。Jim可能從來沒想給這個(gè)代碼寫個(gè)文檔,可能現(xiàn)在他也是被煩透了,寫了一個(gè)。

三、Rake如何工作

開始我想給這個(gè)部分起名為"How to get wasted with Rake"。那么我想喝點(diǎn)酒,該怎么做呢?

1、去買酒

2、喝酒

3、喝醉

如果我要使用Rake完成這個(gè)任務(wù),我會創(chuàng)建一個(gè)“Rakefile”文件:

  1. task :purchaseAlcohol do    
  2.     puts "Purchased Vodka"  
  3. end  
  4. task :mixDrink do    
  5.     puts "Mixed Fuzzy Navel"end  
  6. task :getSmashed do    
  7.     puts "Dood, everthing's blurry, can I halff noth'r drinnnk?"  
  8. end 

這樣我可以在這個(gè)Rakefile的目錄,分別運(yùn)行這些任務(wù):
 

  1. $ Rake purchaseAlcohol   
  2.   Purchased Vodka  
  3. $ Rake mixDrink   
  4.   Mixed Fuzzy Navel  
  5. $ Rake getSmashed   
  6.   Dood, everthing's blurry, can I halff noth'r drinnnk? 

酷!但是從順序上看,我可以用任何的順序運(yùn)行這個(gè)任務(wù)。比如喝醉在買酒或者喝酒之前。當(dāng)然這不符合人的習(xí)慣。

四、Rake的順序

  1. task :purchaseAlcohol do    
  2.      puts "Purchased Vodka"  
  3. end  
  4. task :mixDrink => :purchaseAlcohol do    
  5.      puts "Mixed Fuzzy Navel"endtask :getSmashed => :mixDrink do    
  6.      puts "Dood, everthing's blurry, can I halff noth'r drinnnk?"  
  7. end 

這樣,如果想喝酒,就得先去買,如果想喝醉,就得先喝酒。

  1. $ Rake purchaseAlcohol   
  2.   Purchased Vodka  
  3. $ Rake mixDrink           
  4.   Purchased Vodka Mixed Fuzzy Navel  
  5. $ Rake getSmashed   
  6.   Purchased Vodka Mixed Fuzzy Navel   
  7. Dood, everthing's blurry, can I halff noth'r drinnnk? 

看到了吧,我喝醉和,因?yàn)榫埔呀?jīng)買了,也被我喝了。現(xiàn)在,你的欲望無法滿足了,你想讓你的朋友加入進(jìn)來。就像一個(gè)團(tuán)隊(duì)的開發(fā),如果你想加入一個(gè)新人,你得有合適的規(guī)劃。你得有文檔。那么問題來了。

#p#

五、如何給我的Rake添加文檔

Rake添加文檔非常的方便,使用“desc”就可以了:

  1. desc "This task will purchase your Vodka"  
  2. task :purchaseAlcohol do    
  3.      puts "Purchased Vodka"  
  4. end  
  5. desc "This task will mix a good cocktail"  
  6. task :mixDrink => :purchaseAlcohol do    
  7.      puts "Mixed Fuzzy Navel"  
  8. end  
  9. desc "This task will drink one too many"  
  10. task :getSmashed => :mixDrink do    
  11.      puts "Dood, everthing's blurry, can I halff noth'r drinnnk?"  
  12. end 

看到了吧,我的每個(gè)任務(wù)都添加了desc,這樣我們可以輸入"Rake -T"或者"Rake --tasks":

  1. $Rake --tasks   
  2. Rake getSmashed       # This task will drink one too many   
  3. Rake mixDrink         # This task will mix a good cocktail   
  4. Rake purchaseAlcohol  # This task will purchase your Vodka 

簡單乎?呵呵

六、Rake的命名空間

當(dāng)你開始酗酒,并且開始使用大量的Rake任務(wù)的時(shí)候,你需要一個(gè)好方法將他們分類,這時(shí)用到了命名空間,如果我在上面的例子使用了命名空間,那么:

  1. namespace :alcoholic do    
  2.    desc "This task will purchase your Vodka"    
  3.    task :purchaseAlcohol do     
  4.       puts "Purchased Vodka"   
  5.    end    
  6.    desc "This task will mix a good cocktail"    
  7.    task :mixDrink => :purchaseAlcohol do      
  8.        puts "Mixed Fuzzy Navel"    
  9.    end   
  10.    desc "This task will drink one too many"    
  11.    task :getSmashed => :mixDrink do      
  12.        puts "Dood, everthing's blurry, can I halff noth'r drinnnk?"    
  13.    end  
  14. end 

命名空間允許你將一些任務(wù)放到特定的分類中,在一個(gè)Rakefile中,你可以加入幾個(gè)命名空間。運(yùn)行Rake --tasks

  1. Rake alcoholic:getSmashed        # This task will drink one too many  
  2. Rake alcoholic:mixDrink          # This task will mix a good cocktail  
  3. Rake alcoholic:purchaseAlcohol  # This task will purchase your Vodka 

所以如果想運(yùn)行這個(gè)任務(wù),只要輸入 Rake alcoholic:getSmashed:

七、如何寫一個(gè)有用的Ruby任務(wù)

最近,我想用Ruby創(chuàng)建幾個(gè)文件夾:

  1. desc "Create blank directories if they don't already exist"  
  2. task(:create_directories) do      
  3.     # The folders I need to create    
  4.     shared_folders = ["icons","images","groups"]      
  5.  
  6. for folder in shared_folders          
  7.  
  8.     # Check to see if it exists      
  9.     if File.exists?(folder)        
  10.        puts "#{folder} exists"      
  11.     else        
  12.        puts "#{folder} doesn't exist so we're creating"        
  13.        Dir.mkdir "#{folder}"      
  14.     end        
  15.   end  
  16. end 

當(dāng)然,還可以在Rake中使用更多的 文件工具File Utils,或者加入其他的部分。

八、如何為我的Rails應(yīng)用寫一個(gè)Rake任務(wù)

一個(gè)Rails應(yīng)用中,已經(jīng)有了一些Rake任務(wù),你可以在你的項(xiàng)目目錄里運(yùn)行:Rake --tasks。為了給你的Rails應(yīng)用添加一個(gè)新的任務(wù),你可以打開/lib/tasks目錄(已經(jīng)存在的),添加一個(gè)叫something.Rake的文件,這個(gè)任務(wù)會被自動的檢索到,這些任務(wù)會被添加到Rake tasks列表中,你可以在根目錄里運(yùn)行他們,現(xiàn)在把我們上面的例子放到這個(gè)Rails應(yīng)用中。

  1. utils.Rake  
  2. namespace :utils do    
  3.    desc "Create blank directories if they don't already exist"    
  4.    task(:create_directories) do       
  5.      # The folders I need to create      
  6.      shared_folders = ["icons","images","groups"]                
  7.  
  8.      for folder in shared_folders                
  9.            
  10.          # Check to see if it exists        
  11.          if File.exists?("#{Rails_ROOT}/public/#{folder}")          
  12.          puts "#{Rails_ROOT}/public/#{folder} exists"        
  13.          else          
  14.          puts "#{Rails_ROOT}/public/#{folder} doesn't exist so we're creating"          
  15.          Dir.mkdir "#{Rails_ROOT}/public/#{folder}"        
  16.          end               
  17.      end    
  18.    end  
  19. end 

注意上面的代碼,我使用了#{Rails_ROOT} 來得到Rails應(yīng)用的當(dāng)前位置,現(xiàn)在運(yùn)行“Rake --tasks”,你可以看到我們的任務(wù)已經(jīng)添加到tasks列表中了。

  1. ...  
  2. Rake tmp:pids:clear              # Clears all files in tmp/pids  
  3. Rake tmp:sessions:clear          # Clears all files in tmp/sessions  
  4. Rake tmp:sockets:clear           # Clears all files in tmp/sockets  
  5. Rake utils:create_directories    # Create blank directories if they don't already exist  
  6. ... 

#p#

九、如何在任務(wù)中調(diào)用Rails的model

呵呵,這個(gè)正是我最多使用Rake的地方,寫一個(gè)Rake任務(wù),代替原來需要手工操作的地方,或者一些任務(wù)代替經(jīng)常需要按照計(jì)劃自動執(zhí)行(使用 cronjobs)的事情。就像我開頭說的那樣我用Rake任務(wù)執(zhí)行下面的擦作:

1、給列表中的用戶發(fā)送郵件

2、每晚數(shù)據(jù)的計(jì)算和報(bào)告

3、過期或重新生成緩存

4、備份數(shù)據(jù)和svn版本

5、運(yùn)行數(shù)據(jù)處理腳本

這個(gè)補(bǔ)充了原來的功能,而且相當(dāng)簡單。下面這個(gè)任務(wù)是檢查用戶的過期時(shí)間,對快過期的用戶發(fā)送郵件。

  1. utils.Rake  
  2. namespace :utils do    
  3.    desc "Finds soon to expire subscriptions and emails users"   
  4.    task(:send_expire_soon_emails => :environment) do         
  5.          # Find users to email          
  6.          for user in User.members_soon_to_expire                  
  7.                   puts "Emailing #{user.name}"                  
  8.                   UserNotifier.deliver_expire_soon_notification(user)          
  9.          end    
  10.    end  
  11. end 

使用你的model只用一步,"=> :environment"。

  1. task(:send_expire_soon_emails => :environment) do
  2.  

如果在我的開發(fā)環(huán)境上運(yùn)行這個(gè)任務(wù),我只需要"Rake utils:send_expire_soon_emails",如果我想在產(chǎn)品環(huán)境下運(yùn)行這個(gè)任務(wù),我需要"Rake Rails_ENV=production utils:send_expire_soon_emails"。

原文作者:Jason Seifer

文章來源:http://jasonseifer.com/2010/04/06/rake-tutorial

【編輯推薦】

  1. 跑起來吧 Ruby on Rails開發(fā)初體驗(yàn)
  2. Ruby on Rails性能優(yōu)化七劍
  3. Ruby on Rails應(yīng)用技巧全解析
  4. 總結(jié)各種Ruby on Rails命令
  5. Ruby on Rails驗(yàn)證輸入技術(shù)講解
責(zé)任編輯:王曉東 來源: 博客
相關(guān)推薦

2013-07-23 09:02:48

Facebook Ho應(yīng)用設(shè)計(jì)

2012-10-17 13:50:25

2018-11-06 15:56:25

西門子工業(yè)網(wǎng)絡(luò)智能制造

2011-09-26 14:28:28

水果忍者

2014-04-14 10:06:22

.Net 開源

2016-12-12 14:19:59

LLVMClangApple

2017-01-15 11:01:56

2018-02-07 10:08:02

應(yīng)用服務(wù)器網(wǎng)絡(luò)數(shù)據(jù)庫

2011-12-14 11:14:29

IT外包變化岳雷

2015-07-14 15:44:18

渠道華為

2012-06-19 16:11:56

2017-11-27 11:02:46

高并發(fā)突發(fā)池系統(tǒng)架構(gòu)王者榮耀

2015-06-18 11:28:18

谷歌

2021-09-05 18:26:42

2017-10-30 08:20:16

王者榮耀騰訊云游戲

2013-02-20 10:05:21

吳剛捕魚達(dá)人

2022-10-21 11:50:04

2016-12-12 14:24:25

蘋果Aqua界面

2023-09-26 07:33:41

2011-01-04 10:00:41

云計(jì)算YunTable
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號