はじめに
最近、rbenvでどうしてもrubyのglobalバージョンがうまく切り替わらなくて、困っていました。
色々検索して、複数の記事を参照して設定変更したりしたけど、解決できていません..
そして、stack overflow経由して、rbenvのドキュメントにたどり着き、解決できました。
rbenvがどうやってrubyバージョンを決めるのか、についてもようやく理解できたので、メモとして記録しておきます。
rbenvでRubyのバージョンを確定する順番
rbenvドキュメント Choosing the Ruby Versionによると、
rbenvが利用するrubyバージョンを確定する順番は、
-
RBENV_VERSION環境変数を確認する。もし指定があれば、そのバージョンにする。RBENV_VERSION環境変数は
export RBENV_VERSION= x.x.xコマンドラインで切り替えられる。(set by部分はRBENV_VERSION environment variableになる。) -
.ruby-versionファイルを確認する。まずスクリプトを実行しようとしているディレクトリとその親ディレクトリ、ファイルシステムのルートに達するまで検索して、最初に見つかった.ruby-versionファイルにあるバージョンを指定する。 -
そして、カレントディレクトリとその親ディレクトリから検索して、ファイルシステムのルートに達するまで、最初に見つかった
.ruby-versionファイルにあるバージョンを指定する。rbenv localコマンで、カレントディレクトリにある.ruby-versionファイルを修正できる。 -
最後にglobal
~/.rbenv/versionファイルを確認する。rbenv globalコマンで指定できる。もしglobalバージョンファイルが存在しない場合、rbenvはsystemRubyを利用する。 (いわゆるPATHが通っていない状況)
つまり、rbenvは RBENV_VERSION > .ruby-version > ~/.rbenv/version の確認順番でrubyバージョンを決める。
ドキュメントのほか、こちらの記事も合わせてrbenvでRubyのバージョンを指定する方法も参照できる。
Rubyバージョンが切り替わらない時、他参照できる記事
Rubyのバージョンが切り替わらない時の対処法!
rbenvでバージョンがうまく切り替わらなかった時にやったこと
[Ruby]rbenvでバージョンが切り替わらない時にやるべきこと
ほとんどの場合はこちらの記事を参照して、解決できるはずと思うけど、私の場合は、解決できなかった...
今回の状況: globalバージョンを設定しても、切り替わらない
$ rbenv global 2.7.4
$ rbenv versions
system
* 2.6.9 (set by /Users/username/.ruby-version)
2.7.4
3.1.1
globalバージョン指定したけど、切り替わっていない
PATHの設定ができているけど
open ~/.zshrc で確認したら、既にPATHが入っている
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init - zsh)"
which rubyで確認して、経路は問題なさそう
$ which ruby
/Users/username/.rbenv/shims/ruby
.rbenv/version内のバージョンが替わっているらしいけど
$ cat ~/.rbenv/version
2.7.4
早速他のバージョンでもう一度試したら、確かに.rbenv/versionが反映できている
$ rbenv global 3.1.1
$ cat ~/.rbenv/version
3.1.1
けど、rubyバージョンは切り替わっていない...
$ ruby -v
ruby 2.6.9p207 (2021-11-24 revision 67954) [x86_64-darwin20]
$ rbenv versions
system
* 2.6.9 (set by /Users/username/.ruby-version)
2.7.4
3.1.1
.ruby-versionが問題らしい
ここで気づいた点は、* 2.6.9 (set by /Users/username/.ruby-version)のところ。
他の記事を参照した時、rbenvがうまく動いたら、
(set by /Users/username/.rbenv/version)が表示されるべきだという。
なるほど、じゃ何でこの.ruby-versionになっているだろう..?
解決策:ホームディレクトリ下に.ruby-versionファイルを置かないこと
検索キーワードを変えて再度検索したところ、この回答に辿り着いた
rbenv not changing ruby version(stack overflow上の英語質問)
Finally, make sure your
$HOMEfolder doesn't have a.ruby-versionfile that you may have created by accident if you were to have done$ rbenv local <ruby-version>in your$HOMEfolder.
Doing$ rbenv global <ruby-version>modifies the$HOME/.rbenv/versionfile, and the existence of a.ruby-versionfile in the$HOMEfolder would override the version set by$HOME/.rbenv/version.
なるほど! !
rubyのglobalバージョンを切り替えようとして、.rbenv/versionの内容が変更したとしても、.ruby-versionファイルがあるから、.ruby-versionファイルにあるバージョンが優先して設定される。
おそらく、誤ってでホームディレクトリで$ rbenv localを実行したから、.ruby-versionファイル生成された。
とりあえず早速ファイルを削除する!
.ruby-versionファイルを削除したら、問題は無事解決!
早速ホームディレクトリ下の.ruby-versionファイルを削除して、バージョン変更してみると
$ rbenv global 2.7.4
$ rbenv versions
system
2.6.9
* 2.7.4 (set by /Users/username/.rbenv/version)
3.1.1
$ ruby -v
ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-darwin20]
ようやくバージョンが切り替わった!
.ruby-versionと.rbenv/versionの違い
ちなみに、この.ruby-versionファイルは何の役割だろう.
調べたら、下記の記事を見つけました。
rbenv の global バージョンが変わらなくて困ったこと 《global と local》
globalというのは、そのPCがデフォルトで使うバージョンを設定することです。
で、localってのがPCの中の一部、
例えば特定のプロジェクトファイル以下で使うバージョンを指定することです。
このlocalでのバージョン指定をしているのが.ruby-versionというファイルです。
このファイルがあるフォルダ以下には
.ruby-versionファイルに記載されたバージョンのrubyが動きます。
つまり、
通常globalバージョンを指定した時、.rbenv/versionが動くけど、
localバージョンを指定した時、.ruby-versionファイルが生成され、.ruby-versionファイルに記載されたバージョンのrubyが優先して指定される。
バージョン指定ができない時、.ruby-versionファイルもチェックして
こうみると、ホームディレクトリ以外のディレクトリでも、もし.ruby-versionが存在する場合、このディレクトリ下でglobalバージョンを指定しようとしても、.ruby-versionに記載されたバージョンの方が優先されるから、バージョンの切り替えができない?
検証として、localバージョンを指定したことあるディレクトリを見つけて、globalバージョン指定しようとしたら、何も替わってない。
$ rbenv global 3.1.1
$ rbenv versions
system
* 2.6.9 (set by /Users/username/app/.ruby-version)
2.7.4
3.1.1
なるほど、localバージョンが優先して指定されているから、globalバージョンが切り替わらない。
いや、ここまでみると、そもそもこれがlocalバージョンが指定できる仕組みだよね...
恥ずかしいけど、rubyバージョン切り替えの仕組みはようやく理解できた..
終わりに
今回私のケースは、本当に稀にある状況かもしれないが、(初学者としても笑われるかも..)
もし他の記事を参照して、PATH設定なども色々やったけど、まだ解決できていない時、.ruby-versionもチェックしてみたら..との話でした。