そうだ、Rubyをやろう(8日目)
Bundlerというものがあるらしい
今回の記事は、Mac OS X上で、rbenvとBundlerを使って、システム全体への依存性を極力排除した上で、独立した環境で動作するRuby + SQLiteの簡単なアプリを作ってみる、という主旨です。rbenvのインストールは、前回の記事で実施済みです。
OS X 10.9.2, Ruby 2.1.1, SQLite3 1.3.9
プログラムを書いていると、「ちょっとしたこと」を枯れた共通のライブラリを流用して解決したい、なんてことはよくある。例えば、ZIPファイルを解凍して中身を取り出したいだとか、XMLをパースしたいだとか、Base64エンコーディングを使いたいだとか。中には、Rubyの標準APIとして用意されている機能もあるだろう。たとえ標準APIに用意されていなくても、ある程度一般的な機能であれば大抵、どこかの誰かがライブラリとして用意、配布してくれていたりする。
それは、Rubygemsというパッケージ管理システムでインストールすることができ、Rubygemsでインストールするライブラリのプログラムはgemと呼ばれるそうな。
要は、gemを使えば、簡単な手続き(インストールとrequire)で、OSSの恩恵にあずかることができるということだ。
※言うまでもないが、使用する各gemのライセンスは確認しよう。
そうして私は、自分の作成するプログラムで必要な機能のいくつかを、様々なgemをインストールすることでカバーしてきた。もはや、どのプログラムがどのgemのどのバージョンを使用しているのかすらわからなくなってしまった。
前置きが長くなったが、アプリケーションが必要とするgemを、アプリケーション単位で管理できるのがBundlerというものである。
【参考サイト】
・記事中段あたりにBundlerとはなにかの解説あり、わかりやすい
http://d.hatena.ne.jp/kanonji/20120704/1341378341
・Bundler全般の解説
http://shokai.org/blog/archives/7262
http://qiita.com/sumyapp/items/6843ceebbbfc09a2b6ac
・Bundlerをインストールする
$ rbenv exec gem install bundler $ rbenv rehash
・Bundlerの使い方
Bundlerを使うようになると、Rubygemsを直接使うことはほとんどなくなる。
たとえば、これからSampleAppというRubyアプリケーションを開発するとしよう。
プロジェクトの基準ディレクトリを、
~/Documents/SampleApp
としてみる。
たとえば、このプロジェクトでSQLiteを使いたいとする。
Bundlerを使えば、他のプロジェクトに影響することなく、このアプリで使いたい特定のバージョンのSQLite gemを指定することができる。
そのためには、Gemfileというテキストファイルを作成する。
$ touch ~/Documents/SampleApp/Gemfile $ vim ~/Documents/SampleApp/Gemfile # 以下2行を追加 source 'https://rubygems.org' gem 'sqlite3'
以下のコマンドで指定したgemをローカルにインストールする。
このコマンドは、Gemfileが存在するディレクトリ内で実行すること。
$ bundle install --path vendor/bundle
これでSQLiteの最新版がインストールできた。Gemfileでgemのバージョンを指定しなければ最新版がインストールされる。上記のコマンドを実行すると、gemは、~/Documents/SampleApp/vendor/bundle以下にインストールされるので、他のアプリに影響することはない。
gem 'sqlite3', "~>1.3"
Gemfile内のgemの定義を上記のように記述した場合は、1.3以降、2.0以前のバージョンがインストールされる。
gem 'sqlite3', "~>1.3.5"
Gemfile内のgemの定義を上記のように記述した場合は、1.3.5以降、1.4.0以前のバージョンがインストールされる。
では、試しにSQLiteを使ってみる。本当に動くだろうか。
$ touch ~/Documents/SampleApp/test.rb $ vim ~/Documents/SampleApp/test.rb
require 'rubygems' require 'sqlite3' db = SQLite3::Database.new("test.db") sql = <<SQL create table users ( id integer, name varchar(10), email varchar(128) ); SQL db.execute(sql); db.execute("insert into users values(1, 'pizza1', 'pizza1@hotml.co.jp')"); db.execute("insert into users values(2, 'pizza2', 'pizza2@gml.com')"); db.execute("insert into users values(3, 'pizza3', 'pizza3@yah.co.jp')"); db.execute("select * from users") do |row| puts row.join("\t"); end db.close
【実行】
$ bundle exec ruby test.rb 1 pizza1 pizza1@hotml.co.jp 2 pizza2 pizza2@gml.com 3 pizza3 pizza3@yah.co.jp
できた・・・(感動)
実行したカレントディレクトリに、ちゃんとtest.dbファイルができているし、SQLも実行できている。
korehasugoi!!
何より重要なのは、このSampleAppの完成後、他のマシン上でこのアプリを実行する際に、Gemfileを含めてリリースするということだ。そうすることによって、異なった環境でも、もう一度bundle installしてやることで、必要なgemを一括インストールできる。無論、rbenvやBundlerの環境はインストール機に必要になるが、アプリに必要なgemとそのバージョンを1つ1つ確認して手作業で環境構築することに比べれば、Bundlerによるgem管理の威力は大きい。そのアプリが必要とするもの「だけ」、かつ「必要なバージョンを指定できる」、そしてそのアプリの動作環境は「他のアプリに影響しない」という点が主な利点であろう。多数のRubyアプリを1台のマシンにインストールするときには、尚更である。
まあ、実際、Bundlerが本格的に役立つのは、どうも、Railsを使うようになってからのような気はする。
ということで、次回はいよいよRuby on Railsの環境構築に挑戦してみようと思う。
それでは。
楽しい時間でした!
またの機会を!
つづく