2015-02-23 23:50

ソースコードリーディングの準備

ソースコードを読みたい

gemのインストール

ソースコードを読んでみようと思い立って、最初はブラウザでgithubのページを開いて地道にファイルを追ったりしていたのですが、やたら時間が掛かる。

なので、ソースコードを読む為の環境を作ってみました。

環境と言ってもそんな仰々しいものではないのですが。

とりあえず、Arelのto_sqlメソッドの挙動を見てみようかなぁ、なんて思っています。

まず、任意のディレクトリにプロジェクトディレクトリを作成しましょう。

terminal.app
$ mkdir arel
$ cd arel

次に、Gemfileを作成します。

arel/Gemfile
source 'https://rubygems.org'

gem 'sqlite3'

gem 'pry'
gem 'pry-byebug'

gem 'activerecord'
gem 'arel'

#プログラム実行時にreadlineのLoadErrorが発生したので追加
gem 'rb-readline'

gemのインストール先を作成してから、bundle installします。

terminal.app
$ mkdir vendor
$ bundle install --path vendor/bundle --jobs=4
Feching gem metadata from https://rubygems.org...........
                   :
                省略

bundle installのオプション--pathは指定したディレクトリにgemファイル群をインストールするものです。

--jobs=オプションを使うことで、指定した数で並列にgemをインストールすることができます。

さて、arel/vendor/bundle/以下にgemがインストールされたと思います。

terminal.app
$ ls -R vendor | less
bundle

vendor/bundle:
ruby

vendor/bundle/ruby:
2.1.0

vendor/bundle/ruby/2.1.0:
bin
build_info
cache
doc
extensions
gems
specifications
            :
            :
         省略

これでgemのインストールが完了しました。

DBの設定

必要なgemのインストールが済んだので、実際にソースコードを読んでみましょう。

としたいところですが、今回はarelのto_sqlメソッドを読む為、DBの設定をしてあげる必要があります。

arelディレクトリ直下にsample.rbを作成して以下の内容を記述しましょう。

terminal.app
$ mkdir sample.rb
arel/sample.rb
1       # -*- coding: utf-8 -*-
2
3       require 'pry'
4       require 'pry-byebug'
5       require 'active_record'
6       require 'arel'
7
8       #DBの接続設定
9       ActiveRecord::Base.establish_connection(
10         adapter: 'sqlite3',
11         database: 'sample.sqlite3' #dbファイル名を指定する。ファイルが存在しなければ自動作成してくれる。
12     )
13
14     #songsテーブルがDBに存在しなかった場合の処理
15     unless ActiveRecord::Base.connection.table_exists? :songs
16         #マイグレーションでsongsテーブルを作成
17         ActiveRecord::Migration.create_table :songs do |t|
18           t.string :name
19           t.string :artist
20         end
21
22       #Songモデルを定義
23       class Song < ActiveRecord::Base; end
24
25       #サンプルレコードを作成
26       Song.create(:name => 'Rock and Roll', :artist => 'Led Zeppelin')
27       Song.create(:name => 'My Generation', :artist => 'The Who')
28       Song.create(:name => 'crossroad', :artist => 'Cream')
29       Song.create(:name => 'Scatterbrain', :artist => 'Jeff Beck')
30     end
31
32     #Arelの初期化
33     Arel::Table.engine = ActiveRecord::Base
34     song = Arel::Table.new :songs
35
36     ##################################################
37     ###このスペースに読みたいソースを呼び出す為のトリガーを記述する
38     puts song.project('*').where(song[:id].eq(1)).to_sql
39     ##################################################
40
41     #DBの切断
42     ActiveRecord::Base.connection.disconnect!

1行目はマジックコメント。

3~6行目で必要なライブラリを読み込んでいます。

8~12行目でDBの接続設定を行っています。

10行目でDBを指定(今回はsqlite3)。

11行目で任意のDBファイル名(今回はsample.sqlite3)を指定します。

14~30行目はsample.sqlite3にsongsテーブルが存在しなかった場合の処理で、主に初回実行時に行う処理です。

16~20行目でsongsテーブルを作成し、22~23行目でsongsテーブルを扱う為のSongモデルを定義、25~29行目ではサンプルレコードをsongsテーブルに作成しています。

32行目~34行目でArelの初期化を行います。

そして、35行目以降で読みたいソースコードを呼び出す為のトリガーとなる処理を記述します。

最後に、DBの接続を切断しています。

さて、早速実行してみましょう。

初回実行時はsongsテーブルを作成するので、次のようになるでしょう。

terminal.app(初回実行時)
$ bundle exec ruby sample.rb
--  create_table(:songs)
      -> 0.0036s
SELECT * FROM "songs" WHERE "songs"."id" = 1

`SELECT * FROM ~"はsample.rbの38行目でputsしている箇所の結果です。

2回目以降の実行時はcreate_tableの項がスキップされます。

terminal.app(2回目以降実行時)
$ bundle exec ruby sample.rb
SELECT * FROM "songs" WHERE "songs"."id" = 1

これで準備ができました。

次回では、今回行った準備を使ってデバッグ、及びソースコードリーディングの練習をしてみます。

次回はこちら ⇒ Pryの使い方