#384 Exploring RubyGems
RubyGemを使うとRailsアプリケーションに簡単に機能を追加することができますが、頭の痛い問題の原因にもなりえます。gemを使うかその機能をゼロから書くかをどうやって決めればいいのでしょうか? もしgemを使うと決めた場合でも、似たような機能を持ったものがいくつもあったときにどれを選べばいいのでしょうか?
今回のエピソードはいつもとは趣向を変えて、gemを調べて自分の目的にもっとも合うものを見つけるためのチップスを紹介します。まず最初に見るべき場所は、The Ruby Toolboxです。ここではプロジェクトがカテゴリに分類されているので、例えば認証のカテゴリで一番人気のあるgemはどれかというようなことが簡単にわかります。
今の時点で、自分のアプリケーションの要求を明確にしておくのがいいでしょう。認証機能を付加するのであれば、FacebookやTwitterのような外部認証プロバイダを介するのか、独自にユーザアカウントとパスワードで認証処理を行なうのかを自問してみる必要があります。もし後者であれば、パスワードをリセットする機能も必要なのか、認証画面の見え方を気にするのか? それぞれのgemは独自の方法で認証を処理しているので、これらはすべて重要な質問で、どのgemを使うかを判断するための助けになります。
gemを選択する上でのもう一つの重要な点は、プロジェクトの活動が活発かどうかです。The Ruby Toolboxでいくらかはわかりますが、候補のgemのGithubリポジトリをチェックすることで、より正確な状況を知ることができます。ここでは、Rails関連のgemではもっとも人気のあるDevise gemに注目してみます。Githubリポジトリを見ると定期的に更新されていることがわかりますが、これは認証という機能の性格上好ましいことです。もし最近1年間で数回しかコミットされていないとしたら、現行バージョンのRailsでは動作しないか次の版がリリースされたときに壊れてしまう可能性があるので、他を探す方がいいでしょう。プロジェクトのissue trackerをチェックすることも参考になるでしょう。未解決と完了のissueの数を比較すると、およそgemの開発者の対応の速さがわかります。Deviseの完了したissueは約2,000件で、これによって貢献者たちが問題解決に積極に取り組んでいることがわかります。
次にRubyGems上でプロジェクトを探し、複数のバージョンのリリース日を比較します。Deviseの最新のリリース日は2012年6月です。これはバグのない安定したリリースであったということを意味しているかも知れません。しかし、Githubリポジトリよりは常に古いものであるということを意識しておくのがいいでしょう。それと同時に、gemの実行時の依存関係についても見ておきましょう。アプリケーションに1つのgemを追加する場合でも、多くの場合はその依存関係も同時に追加しているということを理解しておくことは重要です。その依存関係にあるgemがまた別の依存関係を持っているので、実際にはかなり多数のgemを追加していることになり、そのそれぞれがアップデート時に互換性を壊す可能性を持っています。gemが思ったような動きをしないという問題に直面した時は、依存関係の問題が原因である場合が多いです。
そのため、RailsアプリケーションのGemfile.lock
ファイルはとても重要です。このファイルが、各gemのバージョンと依存関係をすべてロックすることによって、gemの一つに新しいバージョンがリリースされたとしても、bundle updateが実行されない限りは現行のバージョンのままに保ちます。互換性の問題の可能性があるので、このコマンドを実行するときには、不具合が発生しないか注意しておくべきです。また、gemfileにgemを追加する場合は、チルダ(~
)演算子を使ってバージョン番号を指定することで、メジャーなアップデートがあった後でbundle update
を実行しても、最後の部分のバージョン番号が違う版にだけアップデートを行なうようにします。そうすることによって下位互換性が保証されるからです。
ドキュメント
次にドキュメントについて説明します。残念ながら多くのRuby gemでは十分ではない状況ですが、どこを見ればいいかがわかっていれば、ドキュメントは整備されていると言える場合も多くあります。いつもプロジェクトのwikiを見るようにすると、見逃しやすい知識の宝庫が見つかる場合があります。wikiのすべてのページがリンクされていない場合もあるので、「Pages」タブをクリックして全ページを確認するのがいいでしょう。 RubyDoc.infoにRDocがある場合があるので、ここもチェックするようにしましょう。そこではプロジェクトのソースコードに含まれるドキュメントを簡単にブラウズする方法を提供します。ここではあらゆる種類の有用な情報を見つけられる場合が多く、十分な量のドキュメントがなかったとしても、gemに含まれるクラスやメソッドの概要を知ることができるでしょう。
プロジェクトについて学ぶもう一つの優れた方法は、ソースコード自体を読むことです。それによってgemをより深く理解できるだけはなく、面白いトリックを学ぶこともできます。Github上のソースコードをブラウズするか、より見やすくするためにリポジトリをcloneしてローカルでブラウズすることもできます。これをDeviseのソースコードでやってみましょう。このコマンドを実行してリポジトリをcloneします。
$ git clone https://github.com/plataformatec/devise.git
プロジェクトの規模を見積もる一つの方法として、行数をカウントします。そのためには
$ cloc app lib 87 text files. 86 unique files. 23 files ignored. http://cloc.sourceforge.net v 1.56 T=1.0 s (64.0 files/s, 5294.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Ruby 64 762 1513 3019 ------------------------------------------------------------------------------- SUM: 64 762 1513 3019 -------------------------------------------------------------------------------
これを見ると、gemのRubyコードは約3,000行あり、比較的大きなものになっています。Deviseは明らかに認証ライブラリとしては大きめであり、それが使用をためらわせるかも知れません。そうだとしても、提供される機能の数を考慮しなくてはならず、だからこそ使用するgemを決める前にあらかじめ要求仕様は何かを正しく理解しておくことが重要になります。もしより軽量でサンプルな認証のアプローチを求めるのであれば、エピソード250で紹介したようにゼロから書くという選択もあります。その場合はコードは100行程度になります。
もう一つチェックするべきなのは、spec
やtest
ディレクトリのコードの行数です。これによってそのプロジェクトのおおよそのテストカバー率と、gemがちゃんとテストされているかどうかがわかります。
$ cloc test 106 text files. 106 unique files. 14 files ignored. http://cloc.sourceforge.net v 1.56 T=0.5 s (186.0 files/s, 15204.0 lines/s) ------------------------------------------------------------------------------- Language files blank comment code ------------------------------------------------------------------------------- Ruby 88 1386 279 5837 HTML 3 3 3 72 YAML 2 2 5 15 ------------------------------------------------------------------------------- SUM: 93 1391 287 5924 -------------------------------------------------------------------------------
Deviseのコードは6,000行近くあり、テストコードがアプリケーションコードの約2倍あるということなのでテストのカバー率は高いと伺われます。次にgemのソースコードをざっと見ていきます。まず最初はlib
ディレクトリのgemと同じ名前のファイルをチェックしてみます。大抵の場合はこのファイルが一番最初にロードされるものだからです。このファイルを見れば、gemの依存関係と全体構造の概要を知ることができる場合が多いでしょう。次に、もし存在する場合はrailtieファイルを見てみます。Deviseでは、このファイルにあたるのがlib/devise/rails.rb
で、これを見ればこのgemがRailsアプリケーションにロードされたときに何が起こるのかを理解できます。これはフル機能のRails engineなので、app
ディレクトリを持っていて、モデルやコントローラなどのために他のファイルをロードすることができます。またこのファイルはWardenとOmniAuth用のミドルウェアもロードします。このファイルで何が起きているかを理解することは、何か問題が起きてデバッグを行なう状況になったときにとても役に立つでしょう。
gemがengineの場合は、常にapp
ディレクトリをチェックするようにしましょう。その場合は、よく理解しておかなくてはいけないことがたくさんあります。というのも、ある振る舞いをオーバーライドする場合があるので、gemがRailsアプリケーションに提供している機能を知ることが役に立つからです。ここでは省略しますが、engineは基本的にはgemの形をしたRailsアプリケーションそのものなので、全体を一通り見てみることは簡単でしょう。