![]() |
るびくる: |
![]() |
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に続きます。