Rubyでタスクビルダーのrakeを使い始める
Rake入門
RakeとはRuby Makeの略で、rubyで開発されたコードビルドツールです。
しかし、なぜRubyにRakeが必要なのでしょうか?
Rubyのコードはコンパイルする必要がないから、Rakeは必要ないのでは?Rakeには別の目的があることがわかりました。タスク管理ツールとして使うのです...。これには2つの利点があります。
1. スクリプトをタスクとして作成し、実行する
もちろん、自動的に実行させたいタスクはすべてスクリプトで作成することができます。しかし、大規模なアプリケーションでは、データベースのマイグレーション (Railsのdb:migrateタスクのようなもの)、キャッシュのフラッシュ、コードのメンテナンスなど、ほとんどの場合スクリプトを書く必要があります。それぞれのタスクに対して、いくつものスクリプトを書く必要があり、管理が煩雑になります。まあ、それらをタスクとしてまとめて整理することで、管理はかなり楽になるのですが。
2. タスク間の依存関係の追跡と管理
Rakeは、タスク間の依存関係を簡単に管理する方法も提供しています。例えば、"migrate" タスクと "schema:dump" タスクが両方とも "connect_to_database" タスクに依存する場合、"migrate" タスクが呼ばれる前に "connect _to_database" タスクは実行されることになります。
本題に入りましょう。つまり、Rakeでどのようにタスクをスクリプト化するかということです。
逐次実行
Rakeでタスクを定義した後、例えば毎朝起きたときに行うルーチンワークのように、実行する順番を指定することができます。
1. 目覚まし時計をオフにする
2.リフレッシュする
3.コーヒーを入れる
4. 犬の散歩
上記のうちいくつかは、Rakefileに次のように記述されています。
task :turn_off_alarm do
would have liked 5 more minutes, though."
end
task :groom_myself do
puts "Brushed teeth."
puts "Showered."
puts "Shaved."
end
task :make_coffee do
cups = ENV["COFFEE_CUPS"] || 2
puts "Made #{cups} cups of coffee. shakes are gone."
end
task :walk_dog do
puts "Dog walked."
" end
task :ready_for_the_day => [:turn_off_alarm, :groom_myself, :make_coffee, :walk_dog] do
puts "Ready for the day!"
end
rake ready_for_the_day でタスクを実行すると、すべてのタスクが意図した順序で実行されていることが確認できます。
Turned off alarm. would have liked 5 more minutes, though.
Brushed teeth.
Showered.
Shaved.
Made 5 cups of coffee.
Dog walked.
Ready for the day!
また、rake make_coffee COFFEE_CUPS=5 で、コマンド内の変数に値を代入することも可能です。
名前空間
このようにタスクを定義するのはいいのですが、それ以外に仕事関係や交通関係などの定義が必要な場合、すべてのタスクを混在させるのは明らかに不適切です。結局のところ、それらは起きるために行うルーチンワークで、他にやることはないわけですから。
名前空間は、Railsでrake db:migrateのようなタスクを定義するのに役立ち、以下のように名前空間内のコードブロックに上記のタスクを含めることによって、物事の間に明確な境界線を引くことができます。
namespace :morning do
task :turn_of_alarm
....
end
今回は、rake COFFEE_CUPS=3 morning:ready_for_the_day という呼び出しコマンドを少し変更する必要があります。これは rails で rake タスクが呼び出される方法と似ていませんか?
デフォルトのタスク
上記の設定で、もし詳細なタスク名を書き忘れたり書きたくなかったりした場合、rakeを直接実行するとどうなるでしょうか。このような可能性があるため、このような落とし穴をなくす必要があり、以下のようにデフォルトの既定タスクを設定することで対応できます。
task :default => 'morning:turn_off_alarm'
rakeコマンドを直接実行すると、デフォルトのアクションが実行され、アラームをオフにするのに役立ちます。
タスクの記述
タスクが多くなればなるほど、管理上の問題が表面化します。タスクを分類し、それぞれのタスクの目的や機能を示すには、名前空間だけでなく、文書クラスのサポートが必要ですので、タスクをdescで記述してみるとよいでしょう。
...
desc "Make coffee"
task :make_coffee do
cups = ENV["COFFEE_CUPS"] || 2
puts "Made #{cups} cups of coffee. shakes are gone."
end
...
上記の説明は、ドキュメントだけでなく、rake -T を使って各タスクが何をするのかきれいに見ることができます。rake -T の出力はアルファベット順になっています。
rake morning:make_coffee # Make coffee
タスクの呼び出し
Rakeでは、タスク間で相互に呼び出すこともできます。たとえば、次のコードでは、午後にもコーヒーを飲みたいので、定義を繰り返すのではなく、午前中のbrewを使って、一杯飲むだけです。
namespace :afternoon do
task :make_coffee do
Rake::Task['morning:make_coffee'].invoke
puts "Ready for the rest of the day!"
end
end
Rakeスクリプト
まずは、次のような簡単な例から見てみましょう。
あなたが火星のメンバーだとすると、それらの古いバージョン、すなわちYan'er Hu Runなど、週末にあなたは鍋を再生するために車の車側、および集団PCに行くことを計画しています。このような状況に対して、ヒッチハイクで車を探す、魚を焼く、ネットカフェPCの3つのタスクを自分で作成する必要があります。vimを使ってrakefileというファイルを作り(注:Rakeは現在のパスでrakefile, rakefile, RakeFile.rb, rakefile.rbファイルを探します)、次のコードをタイプして入力します。
desc "Task 1 -- Hitch a ride to the busboy"# This is said to be a chore because it's so far away
task :busboy do
puts "Found frustrated man"
end
desc "Task 2 -- grill fish"
task :bitchfish do
puts "Boss, bake nine pounds of fish first"
end
desc "Task 3 -- Internet Cafe PC"
task :pc do
puts "I choose the middle road"
end
コマンドラインツールを開き、このファイルがあるディレクトリに移動して、以下のようなコマンドを実行します。
D:\work>rake busboy
(in D:/work)
Found frustrated man
D:\work>rake bitchfish
(in D:/work)
Boss, bake nine pounds of fish first
D:\work\ruby_works\ruby_book>rake laundry
(in D:/work)
I choose the middle way
(注:テキスト部分は論理的ではなく、純粋に楽しむためのものです...)
分析する。
上の段落を読んで、もうやり方はわかったと思うのですが...。では、より理解を深めるために基本的なことを紹介します。上のコードからわかるように、このファイルには3つのタスクが定義されており、descはその下に定義されているタスクを記述するためにRakeが定義したメソッドです。この説明はRake --tasks (またはRake -T)コマンドを使用したときに画面に出力されます。
D:\work>rake --tasks
(in D:/work)
rake bitchfish #task2 -- grilled fish
rake busboy #mission1 -- hitchhike to the bus (this is supposedly a chore because it's so far away)
rake pc mission 3 -- internet cafe pc
タスクは、Rakeの最も重要なメソッドです。そのメソッドの定義は、task(args, &block)です。タスク本体はブロックであり、この場合は単純にやりたい作業を出力します。重要なのは、次のコードです。
puts "Found frustrated man"
は全く普通のRubyの文であり、putsはRubyで出力を行うための一般的な方法である。このように、RakeタスクはRubyの力をフルに使うことができるので、とても強力です。
ゴーゴーゴーゴー。
次に、依存関係を追加します。
明らかに、私たちが定義したタスクにおいて、"焼き魚"は"車への乗り物"に依存しています(他の場所で焼き魚があるかどうかは分かりませんが、とにかくそこが重要なのです)。そこで、この依存関係をタスク定義に追加する必要があり、修正したファイルは次のようになります。
desc "Task 1 -- Hitch a ride to the bus"
task :busboy do
puts "Found frustrated man"
end
desc "task 2 -- grill fish"
task :bitchfish => :busboy do
puts "Boss, grill nine pounds of fish first"
end
desc "Task 3 -- Internet Cafe PC"
task :pc do
puts "I choose middle"
end
もう一度fish bakeタスクを実行すると、以下のような結果になります。
D:\work>rake bitchfish
(in D:/work)
Found the frustrated man
Boss, grill nine pounds of fish first
名前空間を追加します。
どんなプログラミング言語でもそうですが、たくさんの rake ファイルがあるとき、たくさんのタスクがあるとき、名前の衝突に気をつける必要があり、名前空間は自然な解決方法です。上記の3つのタスクのために、danという名前空間を定義することができます。
namespace :dan do
desc "Task 1 -- Hitch a ride to the busboy"
task :busboy do
puts "Found frustrated man"
end
......
end
もう一度rake -tasksを実行すると、以下のような結果になります。
D:\work >rake --tasks
(in D:/work)
rake dan:bitchfish # task 2 -- grill fish
rake dan:pc # task 3 -- internet cafe pc
rake dan:busboy # task 1 -- hitch a ride to the bus
これで、rake dan:bitchfishを使用して、魚焼きタスクを開始する必要があります。
(ちなみに、rakefileではタスクを分類するために複数の名前空間を使用することができます)。
以上の2点を理解した上で、2つの具体的な例を見てみましょう。
1. タスクの中で別のタスクを呼び出す
タスクがたくさんあるとき、タスクの中に別のタスクを呼び出すことが必要になることがあります。例えば、今日しなければならない仕事をすべて「今日」という一つのタスクとして定義するとします。ファイルの先頭で今日のタスクを定義します。
desc "Today's task"
task :today do
Rake::Task["dan:bitchfish"].invoke
Rake::Task["dan:pc"].invoke
end
namespace :dan do
......
end
このように、他のタスクを呼び出す方法は簡単で、ただ
Rake::Task["task_name"].invoke
メソッドを使えば、うまくいきます。コマンドラインから rake today を起動すると、次のようになります。
D:\work >rake today
(in D:/work)
Found the frustrated man
Boss, first grill nine pounds of fish
I choose the middle
2. デフォルトの割り当てです。
Rakeにデフォルトのタスクを追加して、Rakeコマンドで簡単に起動できるようにすることができます。上記のrakefileでは、以下の方法で"today"タスクをデフォルトタスクにすることができます。
task :default => [:today]
そして、コマンドラインから直接 rake を呼び出すと、今日の rake と同じ出力が得られます。
これは rake タスクの簡単な定義で、以下は修正した rakefile の完全版です。
task :default => [:today]
desc "Today's tasks"
task :today do
Rake::Task["dan:bitchfish"].invoke
Rake::Task["dan:pc"].invoke
end
namesoace :dan do
desc "Task 1 -- hitchhike to the busboy (this is said to be a chore because it's so far away)"
task :busboy do
puts "found frustrated man"
end
desc "task 2 -- grill fish"
task :bitchfish do
puts "Boss, bake nine pounds of fish first"
end
desc "Task 3 -- Internet Cafe PC"
task :pc do
puts "I choose the middle road"
end
end
上記の2つの例を読んで、rakeタスクはすべて理解できたと推定される......。その他は、いくつかのコードガンです。ただ、遊んでみてください。
関連
-
Ruby on Rails ラックミドルウェア基礎学習チュートリアル
-
Rubyの並列処理とグローバルロック
-
RubyでXMLデータ処理ライブラリREXMLを使うための手引き
-
Rubyのデザインパターン開発におけるobserverパターンの一例
-
RubyアプリケーションでHTTPベースのリクエストを送信する簡単な例
-
Rubyのデザインパターン。プログラミングにおけるアピアランスパターンの応用
-
CentOS7でruby on railsの開発環境を構築する。
-
Rubyの4つの比較関数(equal?, eql?, ==, ===)について解説します。
-
Rubyの変数参照に関するいくつかの注意点
-
Ruby on Railsのマイグレーションに関するいくつかの考慮点
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン