<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    [轉(zhuǎn)載]比較冷幽默的rake使用指南

    Posted on 2008-05-09 16:19 xan 閱讀(818) 評論(0)  編輯  收藏 所屬分類: script language
    原文地址: http://blog.csdn.net/smilewater/archive/2007/07/09/1683808.aspx

    RakeMakeAnt

    Rake的意思是Ruby Make,一個用ruby開發(fā)的代碼構(gòu)建工具。Rake的英文意思是耙子,一種很樸實的勞動工具。真的是很貼切,Rake正是一個功能強大、勤勤懇懇的勞動工具。

    Rake會經(jīng)常跟C/C++領(lǐng)域的makeJava世界的Ant進(jìn)行對照,事實上,它們有很多相似的地方。我們先來看一下makeant的歷史。

    make的出現(xiàn)是為了解決批量編譯的問題。對于一個小型的項目來說,用一個腳本文件或者批處理命令來進(jìn)行批量編譯就已經(jīng)足夠好。但是對于大型的項目來說,僅僅為了少數(shù)幾個文件的改變就全部重新進(jìn)行一次編譯無疑是耗時且不必要的。而且,在大型的項目中,往往會有很復(fù)雜的依賴關(guān)系。

    Make的出現(xiàn)就是為了解決這兩個問題,make有兩個優(yōu)點:

    1. Make了解自上次Make運行以來哪些文件發(fā)生了變化,它會僅僅編譯那些發(fā)生變化的文件。

    2. Make會跟蹤文件之間的依賴性,如果文件A依賴于文件B,那么如果兩者都沒有編譯時,Make會首先編譯文件B

    Ant算是一個Java世界的make,它要比make年輕許多(想想make是出現(xiàn)在1972年吧),它除了支持批量編譯之外,還支持單元測試、JavaDoc等任務(wù)。因此,AntJava世界中比Make更加流行。

    但是,為什么Ruby需要Rake

    Ruby代碼不需要編譯,為什么需要Rake?其實,與其說Rake是一個代碼構(gòu)建工具,不如說Rake是一個任務(wù)管理工具,通過Rake我們可以得到兩個好處:

    1. 以任務(wù)的方式創(chuàng)建和運行腳本

    當(dāng)然,你可以用腳本來創(chuàng)建每一個你希望自動運行的任務(wù)。但是,對于大型的應(yīng)用來說,你幾乎總是需要為數(shù)據(jù)庫遷移(比如Railsdb:migrate任務(wù))、清空緩存、或者代碼維護(hù)等等編寫腳本。對于每一項任務(wù),你可能都需要寫若干腳本,這會讓你的管理變得復(fù)雜。那么,把它們用任務(wù)的方式整理到一起,會讓管理變得輕松很多。

    1. 追蹤和管理任務(wù)之間的依賴

    Rake還提供了輕松管理任務(wù)之間依賴的方式。比如,“migrate”任務(wù)和“schemadump”任務(wù)都依賴于 “connect_to_database”任務(wù),那么在“migrate”任務(wù)調(diào)用之前,“connect_to_database”任務(wù)都會被執(zhí)行。

    在哪里可以獲得Rake

    Rake的主頁是在http://rake.rubyforge.org/,在這里你可以獲得Rake的簡單介紹,API以及一些有用文檔的鏈接。可以在http://rubyforge.org/frs/?group_id=50獲得最新版的Rake,在作者寫作時,最新版本是0.7.3

    Rake腳本編寫

    一個簡單腳本

    Rake的腳本相當(dāng)簡單,下面用一個例子進(jìn)行說明。假設(shè)你是一個勤勞的家庭型程序員,在周末你打算為你的家人做一些貢獻(xiàn)。所以你為自己制定了三個任務(wù):買菜、做飯和洗衣服。打開你的文本編輯器,創(chuàng)建一個名叫rakefile的文件(Rake會在當(dāng)前路徑下尋找名叫RakefilerakefileRakeFile.rbrakefile.rbrake文件),并輸入如下內(nèi)容:

    desc "任務(wù)1 -- 買菜"
    task :purchaseVegetables do
    puts "
    到沃爾瑪去買菜。"
    end

    desc "
    任務(wù)2 -- 做飯"
    task :cook do
    puts "
    做一頓香噴噴的飯菜。"
    end

    desc "
    任務(wù)3 -- 洗衣服"
    task :laundry do
    puts "
    把所有衣服扔進(jìn)洗衣機(jī)。"
    end


    打開命令行工具,進(jìn)入這個文件所在目錄,然后運行下面的命令,大致應(yīng)該類似如下結(jié)果:

    D:"work"ruby_works"ruby_book>rake purchaseVegetables
    (in D:/work/ruby_works/ruby_book)
    到沃爾瑪去買菜。

    D:"work"ruby_works"ruby_book>rake cook
    (in D:/work/ruby_works/ruby_book)
    做一頓香噴噴的飯菜。

    D:"work"ruby_works"ruby_book>rake laundry
    (in D:/work/ruby_works/ruby_book)
    把所有衣服扔進(jìn)洗衣機(jī)。


    分析

    很簡單,也很易讀,對吧。這個文件一共定義了3個任務(wù),descRake定義的方法,表示對下面定義任務(wù)的描述。這個描述會在使用Rake --tasks(或者Rake -T,為懶人準(zhǔn)備的快捷方式)命令時輸出在屏幕上。

    D:"work"ruby_works"ruby_book>rake --tasks
    (in D:/work/ruby_works/ruby_book)
    rake cook #
    任務(wù)2 -- 做飯
    rake laundry #
    任務(wù)3 -- 洗衣服
    rake purchaseVegetables #
    任務(wù)1 -- 買菜


    下面的語句定義了purchaseVegetables這個任務(wù),taskRake最重要的方法。它的方法定義是:task(args, &block)。任務(wù)體是一個block,本例中只是簡單輸出你所要做的工作。需要注意的是代碼

    puts "到沃爾瑪去買菜。"

    完全是一個普通的Ruby語句,putsRuby中進(jìn)行輸出的一般性方法,可以看出,Rake任務(wù)可以完全使用Ruby的能力,這使得它非常強大。

    加入依賴關(guān)系

    很顯然,在我們定義的任務(wù)中,做飯是依賴于買菜的(我相信大多數(shù)程序員在周末的冰箱里除了可樂沒有別的)。那么,我們需要在我們的任務(wù)定義中加入這個依賴關(guān)系,修改后的文件如下:

    desc "任務(wù)1 -- 買菜"
    task :purchaseVegetables do
    puts "
    到沃爾瑪去買菜。"
    end

    desc "
    任務(wù)2 -- 做飯"
    task :cook => :purchaseVegetables do
    puts "
    做一頓香噴噴的飯菜。"
    end

    desc "
    任務(wù)3 -- 洗衣服"
    task :laundry do
    puts "
    把所有衣服扔進(jìn)洗衣機(jī)。"
    end


    再次運行做飯任務(wù),你會得到如下結(jié)果:

    D:"work"ruby_works"ruby_book>rake cook
    (in D:/work/ruby_works/ruby_book)
    到沃爾瑪去買菜。
    做一頓香噴噴的飯菜。


    是的,你當(dāng)然需要先買菜,誰讓你是一個冰箱空空如野的程序員呢。

    命名空間

    跟任何編程語言類似,當(dāng)你的rake文件很多時,當(dāng)你有很多任務(wù)的時候,你需要關(guān)注它們的命名沖突問題,命名空間(namespace)就是一個自然的解決方案。你可以為上面的三個任務(wù)定義一個叫做home的命名空間。

    namespace :home do
    desc "
    任務(wù)1 -- 買菜"
    task :purchaseVegetables do
    puts "
    到沃爾瑪去買菜。"
    end
    ……
    end


    再次運行rake --tasks,你會得到如下的結(jié)果:

    D:"work"ruby_works"ruby_book >rake --tasks
    (in D:/work/ruby_works/ruby_book)
    rake home:cook #
    任務(wù)2 -- 做飯
    rake home:laundry #
    任務(wù)3 -- 洗衣服
    rake home:purchaseVegetables #
    任務(wù)1 -- 買菜


    你現(xiàn)在需要使用rake home:cook才能啟動做飯這個任務(wù)了。當(dāng)然,你可以在你的rakefile中使用多個命名空間,對任務(wù)進(jìn)行分類。

    在一個任務(wù)中調(diào)用另外一個任務(wù)

    當(dāng)任務(wù)眾多的時候,你很可能需要在一個任務(wù)中調(diào)用另外一個任務(wù),假設(shè)我們把今天所有要做的工作定義為一個任務(wù):today。在這個任務(wù)中,有兩個任務(wù)需要被調(diào)用,一個是做飯,一個是洗衣服。當(dāng)然,由于做飯依賴于買菜,我們還是需要買菜的(這一步是逃不過去的,呵呵)。在文件的頂部定義一個today的任務(wù):

    desc "今天的任務(wù)"
    task :today do
    Rake::Task["home:cook"].invoke
    Rake::Task["home:laundry"].invoke
    end

    namespace :home do
    ……
    end


    可以看出,調(diào)用其它任務(wù)的方式很簡單,只需要調(diào)用Rake::Task["task_name"].invoke 方法就可以了。在命令行中啟動rake today,可以得到:

    D:"work"ruby_works"ruby_book >rake today
    (in D:/work/ruby_works/ruby_book)
    到沃爾瑪去買菜。
    做一頓香噴噴的飯菜。
    把所有衣服扔進(jìn)洗衣機(jī)。


    默認(rèn)任務(wù)

    可以為Rake增加一個默認(rèn)任務(wù),這樣可以簡單地用Rake命令來觸發(fā)這個默認(rèn)任務(wù),在上面的rakefile中,我們可以用如下方式把“today”任務(wù)作為默認(rèn)任務(wù)。

    task :default => [:today]

    然后調(diào)用直接在命令行中調(diào)用rake,可以得到跟調(diào)用rake today同樣的輸出結(jié)果。

    這就是我們簡單的一個Rake任務(wù)定義,下面是完整的修改后的rakefile

    task :default => [:today]

    desc "
    今天的任務(wù)"
    task :today do
    Rake::Task["home:cook"].invoke
    Rake::Task["home:laundry"].invoke
    end

    namespace :home do

    desc "
    任務(wù)1 -- 買菜"
    task :purchaseVegetables do
    puts "
    到沃爾瑪去買菜。"
    end

    desc "
    任務(wù)2 -- 做飯"
    task :cook => :purchaseVegetables do
    puts "
    做一頓香噴噴的飯菜。"
    end

    desc "
    任務(wù)3 -- 洗衣服"
    task :laundry do
    puts "
    把所有衣服扔進(jìn)洗衣機(jī)。"
    end
    end


    Rails中的Rake任務(wù)

    Rails預(yù)定義了大量的Rake任務(wù),在Rails應(yīng)用的開發(fā)過程中,你想必已經(jīng)在大量使用它們了。在Rails中,所有的Rake任務(wù)都放在rails目錄的lib/tasks目錄下(在作者的環(huán)境下是c:"ruby"lib"ruby"gems"1.8"gems"rails-1.1.4"lib"tasks"),所有的rake任務(wù)都以.rake作為后綴名,這些以.rake結(jié)尾的文件會被自動加載到你的環(huán)境中。你可以到一個已有的Rails工程根目錄下鍵入rake --tasks,可以看到很多的rake任務(wù)已經(jīng)為你整裝待發(fā)了。

    Rails中,最常使用的Rake任務(wù)之一是進(jìn)行數(shù)據(jù)庫的遷移(migration)。數(shù)據(jù)庫遷移程序允許你使用Ruby腳本來定義數(shù)據(jù)庫模式,而db:migrate就是進(jìn)行這個工作的rake任務(wù)。下面我們來分析這個rake任務(wù)。

    db:migrate任務(wù)

    db:migrate任務(wù)存放在lib/tasks/databases.rake文件中。這個文件中定義了所有與數(shù)據(jù)庫操作相關(guān)的任務(wù),我們僅僅抽出db:migrate的定義:

    namespace :db do
    desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x"
    task :migrate => :environment do
    ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
    Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby
    end
    ……
    end



    分析

    首先是命名空間的聲明,migrate任務(wù)的命名空間是db。這也就是我們用db:migrate來引用它的原因。

    下面是一個描述,說明該任務(wù)的功能是把定義在db/migrate目錄下(相對于你的Rails應(yīng)用程序的根目錄)的遷移腳本遷移到數(shù)據(jù)庫中,如果不指定VERSION的話,默認(rèn)是最新版本,否則可以恢復(fù)到一個指定的版本。

    接著是任務(wù)的定義,該任務(wù)依賴于enviroment任務(wù),這個任務(wù)在misc.rake中定義,用來加載Rails的環(huán)境,它的定義相當(dāng)簡單:

    task :environment do
    require(File.join(RAILS_ROOT, 'config', 'environment'))
    end


    用來加載config/environment.rb文件,該文件會加載Rails工作所需要加載的環(huán)境。由于加載了這個環(huán)境,所以ActiveRecord對象現(xiàn)在可以使用,下面就是調(diào)用ActiveRecord::Migrator.migrate方法對每個db/migrate/下的腳本文件進(jìn)行遷移。

    最后會調(diào)用db:schema:dump任務(wù),該任務(wù)的主要作用是產(chǎn)生db/schema.rb文件。該文件用來記錄不同版本的數(shù)據(jù)庫模式。這個任務(wù)的定義就在db:migrate任務(wù)下面不遠(yuǎn)的地方,有興趣的讀者可以自行進(jìn)行分析。

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    posts - 36, comments - 2, trackbacks - 0, articles - 0

    Copyright © xan

    主站蜘蛛池模板: 国产精品色午夜免费视频| 免费国产污网站在线观看| 成年人免费网站在线观看| 亚洲国产精品无码久久久| 99热精品在线免费观看| 亚洲av日韩av不卡在线观看| 三根一起会坏掉的好痛免费三级全黄的视频在线观看 | 亚洲一二成人精品区| 久久青草国产免费观看| 亚洲视频网站在线观看| 国产成人免费高清在线观看| 亚洲熟女乱色一区二区三区| 免费看片免费播放| 国产精品亚洲专区一区| 亚洲国产成人乱码精品女人久久久不卡 | 国产精品免费视频播放器| 国产精品观看在线亚洲人成网| 国产美女做a免费视频软件| 免费视频成人国产精品网站| 久草免费手机视频| 亚洲精品中文字幕乱码影院| 国产无人区码卡二卡三卡免费 | 国产精品免费看久久久久| 国产午夜亚洲精品不卡| 亚洲爽爽一区二区三区| 国产精品免费高清在线观看| 亚洲欧洲视频在线观看| 免费国产成人高清视频网站| 皇色在线免费视频| 亚洲宅男天堂a在线| 无码高潮少妇毛多水多水免费| 色五月五月丁香亚洲综合网| 狠狠亚洲狠狠欧洲2019| 18级成人毛片免费观看| 国产中文在线亚洲精品官网| 免费福利在线视频| 亚洲熟女乱色一区二区三区| 亚洲欧洲∨国产一区二区三区| 免费能直接在线观看黄的视频 | 四虎成年永久免费网站| 毛片亚洲AV无码精品国产午夜|