どうもご無沙汰していますごとけんです。みなさまお元気でしょうか。私はわりと元気です。近況としましては、この会社シングラムが始まってこの7月で10年になりました。ひとえにみなさまのご愛顧のお陰です。感謝感謝です。いたらない点も多々あるかと思いますが、これからも変わらぬご愛顧、これまで以上のご愛顧いただければこれ幸いです。今後ともよろしくお願いいたします。
さて、10周年記念で社内ではいろいろな企画が進行している一方で、案件に埋もれているわたしはあんまり参加できていなくて同僚各位には大変申し訳ないのですが、それなりに面白いものを書かないとなあと思って、締め切りギリギリまで考えた結果(そう、このブログには締め切りがあるのです…進行担当の川井さん遅くなってほんとにごめんなさい…カッコが長くてどこまで書いたかわからなくなりました…あっそうそう、ギリギリまで考えた結果)、Railsを読むことにしました。
Railsの実装って黒魔術だとかなんだとかよくいわれたりもします。わたしも以前はよくわからない挙動に悩まされて、必要なところを海に潜るように息を止めるような感じで読んでその場限りの修正をしたことも何度かありましたが、メタプログラミングが多用されており、なかなかわかりにくいものでした。また、DRYのような思想的な面が紹介されることもありますが全体として一体どんなふうに作られているのか、どんな発想で書かれているのか気になる人は多いと思います。
ちなみに弊社ではRailsを過去にいくつも受託案件のミドルウェア(と言っていいんでしょうか)として採用しているくらいには使っているのですが、私がある程度くわしく知っているのは 2.3.x くらいの Rails でして、正直ここマル3年くらいはあたらしいRailsをあまり深く触っていません。手元では先端の Ruby を一応ビルドするようにしてるのですが、最近はGUI開発を中心に活動していることもあって Rails アプリをプロダクトとして出していないのが実情です…。そこでこのブログを良い機会と考えて今の新しい Rails を読んでみます。
本当は合宿か何かして、一気に読みたいところですがそんな時間はなかなかとれそうもないので地道に読んでみることにしました。なるべくひと通り書き上げてゆくゆくは達人出版会あたりで出してもらえるような内容にできれば!くらいの勢いで書くつもりです。Rails5が出る前に読み終われれば良いのですが・・・
Rails はウェブアプリケーションを作るための枠組み(フレームワーク)です。どういうリクエストが来たらどういう画面を返すか、どういうふうにデータベースを参照したり変更したりするか、というようなことをなるべく少ない手間で書くことができるようにデザインされた枠組みです。Ruby という言語で書かれており、アプリケーションも Ruby で書きます。
ウェブアプリケーションのフレームワークというものはものすごくたくさんありますが、現在の Rails はかなり人気があるほうといえるのではないでしょうか。Rails は2003年に DHH に作られて以来、Rubyのプロジェクトとしては初めて爆発的に成功したソフトウェアで、多くの人の人生がこれで変わったことだと思います。試しに、なんとなく名前を思いついたフレームワークの名前に関係した求人数のトレンドを indeed.com で比較してみました。
図:http://www.indeed.com によるキーワード別の求人数比較
機能や役割がかなり違うので比較していいのかどうかよくわかりませんが、WebLogic や JBoss などの商用アプリケーションサーバーともいい勝負になっています。J2EEの1/2近くも求人があるということがかなり驚きだと思うのです。Railsはこのグラフの範囲では成熟期に入ったようにも見えます。いずれにせよ総じて私が名前を思いつくものは求人が減ってきているようですが、なにが増えてるんでしょうか?最近アンテナが低くて良くないなあと思います。最近人気のフレームワークをご存知の方は教えて下さい。
http://rubyonrails.org/ を見に行くと、2014年4月にリリースされた Rails 4.1 が最新らしいことがわかります。また、 http://rubyonrails.org/download/ では Ruby 2.1.0 の利用を推奨しています。そこで、これらをインストールしてみます。なお、いま使おうとしている OS はたまたま手元にあった CentOS 6.5 です。
まず、下記を参照して rbenv と ruby-build をインストールしておきます。
https://github.com/sstephenson/rbenv#installation
https://github.com/sstephenson/ruby-build#installing-as-an-rbenv-plugin-recommended
とにかく Rails 4.1.0 を動かしたいのでとりあえずおすすめの 2.1.0 をインストールしてみようと思いましたが、Ruby は 2.1.0 からセマンティックバージョニングと称して TEENY (例: 2.1.0 における 0)でのAPI互換性を公言することになったため、Ruby 2.1.2 をインストールすることにします。
% rbenv install 2.1.2 (中略) The Ruby openssl extension was not compiled. Missing the OpenSSL lib? %
どうも openssl のヘッダファイルがないようです。CentOS ですので openssl-devel を yum install してからもう一度インストールしなおしてみます。
% sudo yum install -y openssl-devel (中略) % rbenv install 2.1.2
こんどはうまくいったようです。さっそくこれをこのアカウントの普段使いの Ruby として登録します。
% rbenv global 2.1.2 % rbenv versions * 2.1.2 (set by /home/gotoken/.rbenv/version)
rbenv は Ruby を複数インストールするときに便利なシェル環境の枠組みです。
ちなみに私は普段、会社の Mac Book Pro か Dell の Windows 7 マシンを使っていますが、Mac OS 上でのパッケージ管理は Homebrew を使っていて、言語のたぐいは rbenv、 nodebrew 等を使っています。
つぎにいよいよ rails をインストールします。
% gem install rails (中略) Done installing documentation for actionmailer, actionpack, actionview, activemodel, activerecord, activesupport, arel, builder, bundler, erubis, hike, i18n, mail, mime-types, minitest, multi_json, polyglot, rack, rack-test, rails, railties, sprockets, sprockets-rails, thor, thread_safe, tilt, treetop, tzinfo after 590 seconds % gem list | grep rails rails (4.1.2) sprockets-rails (2.1.3) %
バージョンを指定していなかったので Rails 4.1.2 がインストールされてしまったようです・・・まあよいでしょう。というわけで、ここでの対象を Rails 4.1.2 とします。
http://rubyonrails.org/download/ には次のように書かれています。
Create your application skeleton and start the server:
rails new path/to/your/new/application
cd path/to/your/new/application
rails server
まずはここまでを確認してみます。
ところで、gem install によって rails コマンドはどこにインストールされたでしょうか。which で調べてみます。
% which rails ~/.rbenv/shims/rails
rbenv の管理下では、rails コマンドは rbenv の提供するラッパースクリプトから起動されます。
#!/usr/bin/env bash set -e [ -n "$RBENV_DEBUG" ] && set -x program="${0##*/}" if [ "$program" = "ruby" ]; then for arg; do case "$arg" in -e* | -- ) break ;; */* ) if [ -f "$arg" ]; then export RBENV_DIR="${arg%/*}" break fi ;; esac done fi export RBENV_ROOT="/home/gotoken/.rbenv" exec "/home/gotoken/.rbenv/libexec/rbenv" exec "$program" "$@"
Unix での rails コマンドは Bash スクリプトです。ちょっと読んでみます。
set -e
これはエラーがあったら 0 以外のステータスコードで終われという指示です。
[ -n "$RBENV_DEDEBUG" ]
変数 RBENV_DEDEBUG が空文字列でないことを意味する if です。
set -x
これは Bash をデバッグモードにするものです。
[ -n "$RBENV_DEBUG" ] && set -x
結果として環境変数 RBENV_DEDEBUG が空でなかったら Bash をデバッグモードにします。
program="${0##*/}"
$0 の最後のスラッシュより前を全て取り除いたものを変数 ruby に代入します。このスクリプトだけみても意味はわかりませんが、rbenv では ruby も全く同じスクリプトでラップされているためその場合に特別な処理をするためのものです。
if [ "$program" = "ruby" ]; then
これがその特別な場合です。いまは program の値は rails なのでこの if にマッチする場合は無視します。結果として最後の2行が実行されます。
export RBENV_ROOT="/home/gotoken/.rbenv" exec "/home/gotoken/.rbenv/libexec/rbenv" exec "$program" "$@"
前者は環境変数 RBENV_ROOT の設定。後者は exec による実行です。というわけで
% rails new path/to/your/new/application
を実行すると、
~/.rbenv/libexec/rbenv exec rails new path/to/your/new/application
が実行されます。
この ~/.rbenv/shims/ ディレクトリには環境変数 PATH に置くような実行コマンドに対するいわゆる「シム」が置かれます。
シムというのは画像検索するとわかりますが、それを隙間に挟むことで高さや幅などをあわせる平べったい金具が語源になっていて、互換性を吸収するための小さなライブラリーというような意味があります。
~/.rbenv/libexec/rbenv を全部読んでいると怒られそうなので、逆から読んでみます。最後から3行目に正常時のな実行コマンドが書かれています。
exec "$command_path" "$@"
基本的には command_path を計算してそれを実行するものです。それ以外の部分はパスの計算と環境の設定です。いまの場合は結果として下記が実行されます。
/home/gotoken/.rbenv/libexec/rbenv-exec rails help
そして rbenv-exec から最終的に次が実行されます。
/home/gotoken/.rbenv/versions/2.1.2/bin/rails new path/to/your/new/application
この rails は gem install した rails で以下の Ruby スクリプトです。
#!/home/gotoken/.rbenv/versions/2.1.2/bin/ruby # # This file was generated by RubyGems. # # The application 'railties' is installed as part of a gem, and # this file is here to facilitate running it. # require 'rubygems' version = ">= 0" if ARGV.first str = ARGV.first str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding if str =~ /\A_(.*)_\z/ and Gem::Version.correct?($1) then version = $1 ARGV.shift end end gem 'railties', version load Gem.bin_path('railties', 'rails', version)
これもラッパーみたいなものですがやっと Ruby にたどり着きました。
Rails は人気のあるウェブアプリケーションフレームワークです。Rubyで書かれていて、アプリケーションもRubyで書きます。rbenv はRubyの実行環境を管理するツールです。rbenvは実行コマンドをラップしていて環境を設定してコマンドを実行します。
駆け足になりましたが、今回は rbenv の実行を追いかけることになりました。次号では rails コマンドから読み始めます。
(次号につづく)
世界一複雑なジャンクションの一つフランクフルト中央駅の画像(„Frankfurt Hbf Gleise“ von Eva K – Eva K. Lizenziert unter CC BY-SA 2.5 über Wikimedia Commons) の一部を切り出したものです。フランクフルト中央駅は多くの路線が乗り入れておりそして毎日機能的に稼働しています、きっと。