rbenvの仕組みについて【初学者の備忘録】

# 記事の構成
1. rbenvとは
2. 基本コマンド
3. 仕組みの考察
4. 参考記事

※注意〜筆者は素人エンジニアです。仮説も交じっています〜
※不備がございましたら、ご指摘ください。
※PCはMacです。


## 1. 「rbenv」とは
### rbenv
・Rubyのバージョン管理ツール。
・PC全体で利用するバージョンを設定、切り替えることができる。
・あるディレクトリのみで使いたいバージョンを設定、切り替えができる。

### 上記を理解するための前提知識
・プログラミング言語は、プログラム(ファイル群)である。
・煎じ詰めれば、アプリやソフトウェアもプログラム(ファイル群)である。
・rubyなどのプログラム言語(以下、rubyプログラム)は、PCにインストールする必要がある。
・プログラム言語は、複数のバージョンをインストールすることが可能。(競合しないため)
・rubyで書かれたコードは、PCにインストールしたrubyプログラムを**通して**実行される。(ソースファイルが引数のようなイメージ)

・書いたコードを読み込ませるrubyプログラムのバージョンを変えることで、別のバージョンでrubyファイルを実行することが可能。
・基本はruby2.5.0を使うが、あるプロジェクトではruby2.4.0を使いたいという場面が発生する。
・自分の開発用PCは基本、一台である。

**以上から、普段はruby2.5.0でrubyファイル(アプリ)を実行したいが、あるプロジェクトのみ、ruby2.4.0でrubyファイル(アプリ)を実行したいという需要がうまれた、と推測する。**


## 2. 基本コマンド
・rbenv install [rubyバージョン]
　→rbenvを使ってrubyプログラムをインストールするコマンド
　→rbenvを使う場合は、基本これを使う。

・rbenv global [rubyバージョン]
　→PC全体に適用させたいrubyプログラムのバージョンを設定する。

・rbenv local [rubyバージョン]
　→ディレクトリごとにrubyプログラムのバージョンを設定する。
　→シェル(bashやzsh)で特定のディレクトリに移動して実行することが前提。

## 3. 仕組みの考察
### rbenvの実態は隠しファイル
~/.rbenv/ （ルートディレクトリ）
　→~/.rbenv/shims/ （rubyやgemがインストールしてくれるコマンドのラッパーを保存する）
　→~/.rbenv/version （グローバルに設定しているRubyバージョンを記録するファイル。rbenv globalコマンド実行時に作成される）
　→~/.rbenv/versions/ （その他のインストールした各種Rubyバージョンをインストールする)
引用元：[rbenvとは - Qiita](https://qiita.com/souichirou/items/d4196faa0df9e4bacf17)

### 仕組み
・rbenvコマンドでインストールしたrubyプログラムは、versionsディレクトリに格納される。
　→ruby2.5.1とruby2.4.0をインストールした場合、「2.5.1」「2.4.0」という名前のディレクトリが作成される。
・shimsディレクトリ内の「ruby」という名前のファイルが、ローカルもグローバルも含めて、バージョンを切り替えてくれる。(はず)

### 上記を理解する前提知識
・シェルで、デフォルトで実行できるコマンドは、全てプログラム(ファイル)であり、PCのどこかに保存されている。
　→「cd」「mkdir」「ls」など。
・シェルで、ファイルを実行する際は、絶対パスか相対パスを指定する必要がある。

・毎回パスを指定するのは大変なので、環境変数という機能が生み出された。
・環境変数を設定することによって、どのディレクトリにいても「cd」「mkdir」「ls」と打ち込むだけで実行できる。

・rubyのファイルを実行する際は、rubyのファイルが存在するディレクトリに移動して

```
ruby [ファイル名.rb] [引数]
```
の形で実行する。
・rbenvを導入する前までは、先頭のrubyは、rubyプログラムそのものを指定している。
・rubyコマンド以前にパスの指定がないため、環境変数が設定されている。

・rbenvを導入して、rubyコマンドを実行する場合、~/.rbenv/shims/内のruby.execファイルが実行される。(rubyプログラムそのものではない)
・なぜなら、PATHという環境変数に、~/.rbenv/shims/のパスが紐づいている。(rbenv導入時に設定。設定が違うとバージョン切り替えがうまくいかない)

```bash:ruby.exec
#!/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="/Users/ユーザー名/.rbenv"
exec "/usr/local/Cellar/rbenv/1.1.2/libexec/rbenv" exec "$program" "$@"
```
・~/.rbenv/versions/ディレクトリ内は、rubyのバージョン名ごとにディレクトリが分かれている。
・ruby.execファイルは、rubyプログラムにリダイレクトさせるプログラムなのでは。
・ruby.execファイルには、おそらくrbenv localやgrobalコマンドによってディレクトリやバージョン指定の状況が追記されていくのでは。


総合すると、
**rubyコマンド実行→ruby.exec起動→バージョン指定したrubyプログラム実行→rubyファイル実行**
の流れと推測する。


## 4. 参考記事(と、おまけ)
###おまけ
・ファイルの拡張子は、特定のアプリケーションと紐づけるために存在する。
　→ファイルを開くたびにどのアプリを利用するかを決めるのは面倒なため。
　→「.txtならメモ帳」「.docxならMicrosoft Word」など。
　→実際は、画像ファイルをメモ帳でも開ける。


###参考記事
rbenvについて
https://qiita.com/Kodak_tmo/items/73147ed4f0eec54d6e94
https://takatoshiono.hatenablog.com/entry/2015/01/09/012040
https://www.qoosky.io/techs/8a0f1d8d9e
https://takatoshiono.hatenablog.com/entry/2015/01/09/012040

バージョン指定について
https://qiita.com/akatsuki174/items/c0384b9903b4b5cbbdaf

PATHについて
https://qiita.com/nbkn/items/01a11392921119fa0153
https://qiita.com/fuwamaki/items/3d8af42cf7abee760a81

~/(チルダ)について
https://wa3.i-3-i.info/word13657.html

ラッパーについて
https://wa3.i-3-i.info/word191.html

.bash_profileについて
http://neos21.hatenablog.com/entry/2017/02/12/142817