るびくる: | |
RB(あーるびー): |
はじめまして。Rubyマスコットキャラクターのるびくるです! |
|
堂々と名乗ってるけど、「自称」マスコットキャラクターだよね? 公式じゃないよね。 |
|
あれ、RBいま何かつぶやかなかった? ちょっとよく聞こえなかったなあ(スチャ) |
|
絶対よく聞こえてたよね!? いま手に何構えたの!? |
|
やだなあ、自己紹介からいきなり武器を持ち出したりしないよー。これAndroidケータイ。 |
|
(ウソだ、今の絶対ケータイを出す音じゃなかった……) |
|
それじゃわくわくさーん、今日のテーマはなんにする? |
|
そうだね。最初はRuby有数の便利ツール、Rakeからにしようか。 |
RakeはRuby-Makeの略で、その名の通りRubyで何かを作ったり、定型的な処理をしたいときに役立ってくれるツールだよ。 |
|
あれ、Ruby-Makeってことは、みたいに |
|
うん。プログラムをコンパイルすることもできなくはないんだけど |
|
うーん、よくイメージが沸かないんだけど……「HTMLファイルを作るためにrakeコマンドを使う」ってどういうこと? |
|
たとえば、るびくるは自分でWebサイトを作ってるよね? |
|
ある! あるよ! |
|
そうだよね。 |
|
なるほど、ちょっとわかってきたよ。それを助けてくれるのがRakeっていうツールなんだね。 |
|
うん。Rakeの便利なところはいろいろあるんだけど、大きな利点はこの3つかな。
|
|
はーい、お願いします! |
まずRakeを使うためには、Rakefileっていう名前のRubyスクリプトが必要になる。 |
desc 'Create hello-rake.txt' task :testfile do open('hello-rake.txt', 'w'){|f| f.write('Hello Rake world.') } end
こんな感じのRakefileを書くと、「testfile」って名前のタスクが定義されたことになる。 |
|
Rakefileって、ファイル名の後ろに「.rb」ってつけなくてもいいの? |
|
うん、付けなくても大丈夫だよ。 |
> rake testfile
こんな風にrakeコマンドを実行すると、Rakefileと同じ場所にあるディレクトリに |
|
へー、思ってたよりシンプルな仕組みなんだね。 |
|
そう。この行は無くてもいいんだけど、この行があればrakeコマンドでタスクの説明を表示してくれるようになる。 |
> rake -T
rake testfile # Create hello-rake.txt
> rake -D
rake testfile
Create hello-rake.txt
ちなみに、 |
|
これを使えば、「あれどんなタスク定義してたっけ」ってなってRakefileの中を何度も読み直さなくてもいいんだね! |
|
とくに大きな違いはないから、どっちを使っても大丈夫だよ。 |
さて、今度は依存関係の解決やコマンドの実行について説明するために、もうちょっと複雑な例として |
- Rakefile
- coolerator/
- curry-block.stuff
- carrot.stuff
- potato.stuff
- onion.stuff
# encoding: utf-8 desc 'カレーを料理するタスク' task :cookcurry => 'curry.dish' desc '冷蔵庫の材料を元に、カレーを作るファイルタスク' file 'curry.dish' => ['coolerator/curry-block.stuff', 'coolerator/carrot.stuff', 'coolerator/potato.stuff', 'coolerator/onion.stuff'] do |task| # 冷蔵庫ディレクトリ(coolerator)に移動 cd 'coolerator/' do # 野菜を切るために、「cut-food」コマンドを実行 sh "cut-food carrot.stuff potato.stuff onion.stuff" # カレールーと全ての野菜を煮込むために、「boil-food」コマンドを実行 sh "boil-food *.stuff" end end
ただし、普通のファイルを扱うRakefileだと、るびくるには分かりにくいかもしれないから |
|
わたしがごはんにしか興味ないような言い方はやめてくれる!? |
|
それじゃ、試しに |
> rake -T
rake cookcurry # カレーを料理するタスク
rake curry.dish # 冷蔵庫の材料を元に、カレーを作るファイルタスク
>
最初のRakefileの例と同じで、descメソッドで説明をつけたタスクが一覧表示されてるんだね。 |
|
うん。たぶんるびくるが疑問に思ってるのは、この部分のことだよね? |
desc 'カレーを料理するタスク' task :cookcurry => 'curry.dish'
そうそう! 最初の例では、 |
|
うん。今回の例では、cookcurryタスクの処理を直接書いてない。 |
|
依存関係? |
|
すごく簡単に言うと、「Aを作るためにはBが必要です」っていう関係のこと。 |
|
うーん……それはもちろん、カレーだよね。 |
|
そう。それじゃカレーを作るためには、何が必要になる? |
|
カレーの材料……つまり、カレールーとか、にんじん、ジャガイモ、タマネギ、ピクルスなんかが必要になるね。 |
|
最後のは必要ってわけじゃないと思うけど、だいたいそんな感じだね。 |
desc 'カレーを料理するタスク' task :cookcurry => 'curry.dish' desc '材料を元に、カレーを作るファイルタスク' file 'curry.dish' => ['curry-block.stuff', 'carrot.stuff', 'potato.stuff', 'onion.stuff'] do |task| (中略) end
この定義は、こういう関係を表してるんだ。
|
|
なるほど、何となく分かってきたよ! |
|
そう。Rakeはこんな風に、「Aを作るためにBが必要」「Bを作るためにCが必要」っていうような |
それじゃ、依存関係のことはだいたい説明できたと思うから |
# encoding: utf-8 desc 'カレーを料理するタスク' task :cookcurry => 'curry.dish' desc '冷蔵庫の材料を元に、カレーを作るファイルタスク' file 'curry.dish' => ['coolerator/curry-block.stuff', 'coolerator/carrot.stuff', 'coolerator/potato.stuff', 'coolerator/onion.stuff'] do |task| # 冷蔵庫ディレクトリ(coolerator)に移動 cd 'coolerator/' do # 野菜を切るために、「cut-food」コマンドを実行 sh "cut-food carrot.stuff potato.stuff onion.stuff" # カレールーと全ての野菜を煮込むために、「boil-food」コマンドを実行 sh "boil-food *.stuff" end end
まず、1行目のこのコメントは、エンコーディング宣言だね。 |
# encoding: utf-8
あ、これって確かやつだよね! |
|
ああ、そういえばるびくるのメイン環境はRuby 1.8だったね。 |
|
わたしは1.8ユーザーにも1.9.1以降のユーザーにも優しい |
|
……。 |
desc '冷蔵庫の材料を元に、カレーを作るファイルタスク' file 'curry.dish' => ['coolerator/curry-block.stuff', 'coolerator/carrot.stuff', 'coolerator/potato.stuff', 'coolerator/onion.stuff'] do |task|
ここではtaskメソッドの代わりに、fileメソッドを使ってファイルタスクを定義してるね。 |
|
ファイルタスクっていうのは、ファイルを作るためのタスクだってことだよね。 |
|
うん。定義したブロック内の処理を実行する、ってところまでは同じなんだけど |
|
そっか。ファイルタスクを使えば、
のどっちかのときにしか、料理をしないようになるんだね。 |
|
そういうこと。だから、基本的には |
# 冷蔵庫ディレクトリ(coolerator)に移動 cd 'coolerator/' do
これはcdメソッドをブロックつきで実行して、カレントディレクトリを移動してるところだね。 |
|
あれ、cdメソッドって標準のメソッドにあったっけ? |
|
お、いいところに気が付いたね。 |
|
あー、それ確かにすごい便利! |
|
ああ、僕も手元のスクリプトの半分くらいには |
# 冷蔵庫ディレクトリ(coolerator)に移動 cd 'coolerator/' do # 野菜を切るために、「cut-food」コマンドを実行 sh "cut-food carrot.stuff potato.stuff onion.stuff" # カレールーと全ての野菜を煮込むために、「boil-food」コマンドを実行 sh "boil-food *.stuff" end
最後に、cdブロックの内側を見てみようか。ここが実際に料理をしてるところだね。 |
|
みたいなものってこと? |
|
そうだね。shメソッドはRakeの拡張なんだけど、基本的にはRuby組み込みのsystemメソッドと同じ機能を持ってる。 |
> rake cookcurry
cut-food carrot.stuff potato.stuff onion.stuff
boil-food *.stuff
>
cut-foodコマンドとboil-foodコマンドの実行内容が表示されてるんだね。これは確かにわかりやすいね! |
それじゃ、パート1:概要編はここで終わりにしようか。 |
|
えー、この話次回に続くの!? |
|
え、今さら!? |
|
いやー、連載だとは聞いてたんだけど、てっきりRakeの話自体は今回で終わるものなんだと思い込んでまして…… |
|
るびくるのその、人の話が左の耳から入って右の耳にそのまま抜けていく習性、どうにかならないの? |
パート2:実践編1に続きます。