rubyバージョン管理どうやってる？

## はじめに

環境構築の時は、やれそのバージョンのrubyがインストールされてないだの、別のバージョンを使ってるだの、よくエラーで怒られていました。

今回の内容を読めば、

:::note info
- **rubyのバージョン管理はどこで行われているか**
- **どうやって使いたいバージョンを指定するか**
- **どんな仕組みか**

:::

がわかるようになります

rubyのバージョンには以下の2種類があります。

- **ruby version local (そのディレクトリ内)**
- **ruby version global(全体のデフォルト)**

それぞれの設定の仕方を確認しましょう

# 目次

- [はじめに](#はじめに)
- [rbenv](#rbenv)
- [version(グローバル)](#versionグローバル)
- [version(ローカル)](#versionローカル)



## ``rbenv``
まずは、**rbenv**について確認していきます。

rbenv
- **rb : Ruby の略**
- **env : Environment（環境）の略**
つまり、rbenv は **“Rubyの環境”** という意味です。

rbenv は Rubyのバージョンを切り替えて、異なるRuby環境を簡単に管理するためのツール です

```
- プロジェクトAでは Ruby 2.7
- プロジェクトBでは Ruby 3.2
```
といった感じで、**環境（environment）ごとに使うRubyを自由に変えられる**のがポイントです。

要するに、rbenv は “Rubyのバージョンを切り替えて環境を管理するツール” という意味合いで名付けられています。


### rbenv の管理ファイル

以下のコマンドで現在インストール可能なバージョンを確認できて、
```bash
rbenv install --list(-l)
```
```bash
3.1.6
3.2.5
3.3.5
jruby-9.4.8.0
mruby-3.3.0
picoruby-3.0.0
truffleruby-24.1.0
truffleruby+graalvm-24.1.0
```
以下のコマンドでインストールできます。

```bash
rbenv install 3.2.2
```
実行すると、
``~/.rbenv/versions/`` の中に 3.2.2 というフォルダが作られ、その中にRubyがインストールされます。

```bash
~/.rbenv/versions/
├── 2.7.6/
├── 3.1.2/
└── 3.2.2/
```


## version(グローバル)
システム全体のデフォルトバージョンを管理するグローバルバージョンについて確認しましょう。

まずはホームディレクトリに移動してみましょう

```bash
cd ~ (/home/user名/)
```

次にディレクトリ構造を見てみる
```bash
ls -a (--all)
```

すると、``.rbenv/``という隠しディレクトリが見つかるはず
その中を確認すると色々書いてあると思いますが、バージョン管理をしてくれている部分だけを抽出すると、
```bash
home/
└──user名/
   └──.rbenv/
        ├── version
        └── versions/
```
- ``version``がこのシステム全体(``home/ユーザー名/``ディレクトリ以下の)のデフォルトのrubyのバージョン(**global version**)を指定してくれるファイル
- ``versions/``がインストールしたrubyのバージョンが管理されてるディレクトリ

<br>

こんな感じ
```bash
~/.rbenv/
├── version # globalのバージョンが書いてあるファイル
└── versions/ # インストールしたrubyのバージョンが管理されてるディレクトリ
    ├── 2.7.6/
    ├── 3.1.2/
    └── 3.2.2/
```
複数バージョンをインストールしていると、``versions/``の下で管理してくれています。

バージョンディレクトリの下を確認してみると
```bash
~/.rbenv/
├── version # globalのバージョンが書いてあるファイル
└── versions/ # インストールしたrubyのバージョンが管理されてるディレクトリ
    ├── 2.7.6/
    ├── 3.1.2/
    └── 3.2.2/ # この下の階層には色んな設定が書いてある
        ├──bin/ 
        ├──include/
        ├──lib/
        └──share/
```

これらのフォルダの中に、Rubyの実行ファイル (bin/ruby) や gem などが含まれている。

なるほど、このversionsディレクトリの下に書いてあるバージョンが使えるということですね。

ということは、このディレクトリまで来れば、自分が使える(インストールした)バージョンを確認できるってことです。

ですが、いちいちこのディレクトリまで来なくても確認できるコマンドがあります。

それが、``rbenv versions``です。

```bash
rbenv versions # インストールされてるrubyのバージョンを確認
  3.1.3
* 3.2.4 (set by /home/shoya/.rbenv/version) # どこで設定されているか書いてある！
  3.3.4
```

バージョン指定を変えたい場合は、以下のコマンドで ``version``ファイルの中身を書き換えてあげます。

```bash
rbenv global 3.2.5
```

このコマンドで、3.2.5バージョンが適用されるようになります。

確認してみます
```bash
rbenv global # このコマンドで確認できる

3.2.5
```
適用されていますね。

このとき、インストールされていない(``versions/``以下に書いていない)バージョンを指定することはできません。「インストールされてないよ」とエラーが返ります。
```bash
rbenv global 3.3.3

rbenv: version `3.3.3' not installed
```

``rbenv global``コマンドが内部的にやっていることを以下のようにも再現できます。

```bash
echo "3.2.5" > version # 絶対にこの名前でファイルを作成すること

# このとき、~/.rbenv/versions以下にないバージョンを書けない
```

ちゃんと入ったか、中身を確認します。
```bash
cat version
```

```bash:version
3.2.5
```
入ってます。

ただ、``rbenv``コマンドを使うことで、**使えるバージョンを管理しながら簡単に設定してくれる**のでそっちを使うのが良いでしょう。


<br>
グローバルバージョンについてまとめると

:::note info
**バージョン番号(文字列)が書かれた ``version``という名前のファイルに書き込む（作る）ことで、``versions/``以下に格納されたrubyのバージョンをホームディレクトリ以下に適用することができる**
:::

ということになります。


## version(ローカル)
それでは、プロジェクトごとに違うrubyのバージョンを適用したいという場合を見ていきます。

例えば、``hoge/``ディレクトリ以下にはデフォルト(グローバルバージョン)とは違うバージョンを適用させたいとします。

そのときは、``.ruby-version``という隠しファイルを``hoge/``ディレクトリ直下に作成してあげるだけです。

今度はこれ

```bash
rbenv local 3.3.5
```

これでhogeディレクトリ以下は3.3.5バージョンのrubyが適用されます。
確認してみます

```bash
rbenv local
```

```
3.3.5
```

では、globalの時同様に、内部的にどんなことをしているかを別のコマンドを使って説明すると

```bash
echo "3.3.5" > .ruby-version 
# ない時は新しくファイルが作成されるし、あれば上書きされます
```

```bash
└──hoge/
    ├──.ruby-version #　この名前のファイルの中にバージョンを書く
    ├── ...
```  

```bash
cat .ruby-version
```
見てみると、
```.ruby-version
3.3.5
```

これで、hogeディレクトリ直下は3.3.5バージョンのrubyが使えるようになりました。

:::note info
**バージョン番号(文字列)が書かれた ``.ruby-version``という名前のファイルを作ることで、``versions/``以下に格納されたrubyのバージョンを現在のディレクトリ以下に適用することができる**
:::


ローカルが設定されていないときは、グローバルが適用されるのですが、その状態で
```
rbenv local
```
をすると
```bash
rbenv: no local version configured for this directory
```
「ローカルバージョンは設定されてないよ」とエラーが発生するので、

普通に今適用されているバージョンを確認したいなら
```bash
ruby -v
```
を使えば良さそうです。

## まとめ

**rubyのバージョン管理はrbenv**
**(ruby environment)がやってくれる！**

```bash
# インストール可能なバージョンの確認
rbenv install list
# rubyの特定のバージョンをインストール
rbenv install バージョン番号
# 今使えるバージョンの確認
rbenv versions

# グローバルバージョンの確認
rbenv global
# グローバルバージョンの設定
rbenv global バージョン番号

#ローカルバージョンの確認
rbenv local 
#ローカルバージョンの設定
rbenv local バージョン番号

#現在適用されているバージョンの確認
ruby -v
```