Ruby環境構築３

# はじめに
前回はRuby、rubygems、Gemについてまとめた。今回はbundlerを使う場合についてまとめる。

# 概要
bundlerはgemを管理してくれるgemだ。具体的には、gemインストール時に依存関係のあるgemを併せてインストールしてくれる。また、アプリケーション単位でgemをインストールできるようにする。

# ディレクトリ構成とインストール
## ディレクトリ構造
前回記載したRubyとrubygemsについては変わらないので省略。今回は/home/ec2-user配下の中を対象にする。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/269452/dcf97cb7-7992-3ce9-6b58-e5d42e4c5a75.png)


## インストール
1. rubyとrubygemsのインストール（前回同様）

    最初にyum install rubyでrubyとrubygemsをインストールする。

2. bundlerのインストール（緑色）

    これも前回と同様と言えば同様だ。rubygemsを使って、bundler（gem）をインストールする。なお、今回のbundlerのようにコマンドがあるgemは/home/ec2-user/配下のbinに置かれる。

3. アプリ用ディレクトリの作成（水色）
    最初にアプリのディレクトリRubyAPP1を作成する。また、vendor/bandleディレクトリを作成する。このディレクトリは、アプリケーション用のgemをインストールする場所だ。（厳密にはなんでもいいが、一般的にはvendor/bandleとするみたい。）

4. GemFileの作成
    このファイルは、アプリケーションで利用するGemを記述する。中身はいたってシンプルだ。今回はactivesupportというgemをインストールする。

    ```ruby
# gemのインストール元
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# 利用するgem一覧
gem "activesupport"
```
source "https://rubygems.org" は、gemのダウンロード元を意味している。そして、gitもダウンロード元として定義されている。

5. gemのインストール
    `bundle install --path vendor/bundle`コマンドで、リストに記載したgemがインストールされる。インストール先は--pathで指定したディレクトリだ。このとき依存関係のあるgemも勝手にインストールしてくれる。インストールしたらGemfile.lockが作成される。これは、インストールされたgemのリストとなる。

    ```ruby
GEM
  remote: https://rubygems.org/
  specs:
​    activesupport (4.2.11)
​      i18n (~> 0.7)
​      minitest (~> 5.1)
​      thread_safe (~> 0.3, >= 0.3.4)
​      tzinfo (~> 1.1)
​    concurrent-ruby (1.1.4)
​    i18n (0.9.5)
​      concurrent-ruby (~> 1.0)
​    minitest (5.11.3)
​    thread_safe (0.3.6)
​    tzinfo (1.2.5)
​      thread_safe (~> 0.1)
PLATFORMS
  ruby
DEPENDENCIES
  activesupport
BUNDLED WITH
   1.17.3
```
なるほど、依存関係と実際に入ったものがよくわかる。
​ 
6. プログラム作成と実行
    ここまできたら、プログラムを作成し実行する。プログラムの内容は以下の通り。

    ```ruby
# Rubygemsを使用することを明示
require 'bundler'
Bundler.setup
# ActiveSupportを使用することを明示
require 'active_support'
# ActiveSupportに含まれる時間系の拡張機能(ライブラリ)を使用することを明示
require 'active_support/time'
# 現在時刻
p Time.now
# 1時間前(60秒*60分)の時刻
p 1.hours.ago
```
`require 'bundler'`と`Bundler.setup`でbundlerのgemを使うことを宣言する。その上で実際のgemをrequireする。

# ポイント
## bundlerはアプリケーション単位にインストールされる
それぞれのディレクトリで`bundle list`を実行すると以下となる。

* RubyAPP1の場合

```bash
[ec2-user@ip-10-0-1-142 RubyAPP1]$ bundle list
Gems included by the bundle:
- activesupport (4.2.11)
- bundler (1.17.3)
- concurrent-ruby (1.1.4)
- i18n (0.9.5)
- minitest (5.11.3)
- thread_safe (0.3.6)
- tzinfo (1.2.5)
```
* RubyAPP2の場合

    ```bash
[ec2-user@ip-10-0-1-142 RubyAPP2]$ bundle list
Gems included by the bundle:
- bundler (1.17.3)
- string-to-bool (0.0.1)
```

## インストール先は一度指定すると記憶される
１回bundole installを実施すると.bundle/configにgemのインストール先が記載される。これにより、次回以降はディレクトリを指定しなくても同じ場所にgemはインストールされる。

```bash
BUNDLE_PATH: "vendor/bundle"
```

## インストール先を指定しない場合はbundlerと同じ場所にインストールされる
初回の`bundle install`でパスを指定し忘れた場合は/home/ec2-user/.gem/ruby/gemsにインストールされる。そして、.bundle/configは作成されない。
`gem list`コマンドをうつとbundlerとインストールされたgemが表示される。

```bash
[ec2-user@ip-10-0-1-142 RubyAPP3]$ bundle list
Gems included by the bundle:
- bundler (1.17.3)
- string-is_int (0.0.1)
```
rubygemsでgemを入れたような扱いに近い。

# まとめ
bundlerがあると、アプリケーションごとにgemを管理してくれるし、依存関係も管理してくれる。基本的にはrubygemsでbundlerを入れた後は、bundlerでgemをインストールするのが分かりやすい。gemを使わないrubyアプリケーションなんて作るつもりはないので、**rubyとbundlerはセットで入れるべし**。