LoginSignup
4
4

More than 3 years have passed since last update.

Gemfile.lock にはインストールされている gem のバージョンが書かれている,わけじゃない

Posted at

Ruby の初心者向け記事を眺めていると,Gemfile.lock について誤解していると思われる記述が目につきます。
そんなアレコレをこの記事では見ていきます。

最初に,Gemfile と Gemfile.lock についておさらいをしておきましょう。

まず,Gemfile はそのプロジェクトで使用する gem を指定するものでしたね。
gem の名前だけでなくバージョンも指定することができます。「○○以上」「○○未満」のような幅をもった指定もできます。また,

gem "hoge", "~> 3.5.2"

と書けば,hoge gem で,「3.5.2 以上,3.6.0 未満」という意味の指定になるのでした。

一方,Gemfile.lock は,Bundler によって生成されるファイルでした。
Gemfile.lock がまだ存在しない状態で,

bundle install

とすると,Bundler は Gemfile の記述を元に gem をインストールしていくのですが,さきほどの記述を例に取ると,hoge gem の「3.5.2 以上,3.6.0 未満」を満たすバージョンのうち,実際に存在している最も高いバージョンの gem を選びます。そしてそのバージョンを Gemfile.lock に記録し,まだインストールされていない場合はインストールします。

ここで以下のような誤解が生じます。

  • Gemfile.lock にはインストールされている gem のバージョンが書かれている。

確かに上述の状況ではそのようになります。
しかし,Gemfile.lock が生成されたあとで当該の gem をアンインストールすることができます。
また,チーム開発などでは,誰かの環境で作られた Gemfile.lock が Git 管理されて自分の手元にやってくることもありますね。この場合,そこに書かれた gem はこちらではまだインストールされていないかもしれません。
それに,Gemfile.lock に書かれていないバージョンの gem もインストールされているかもしれません。

こうしてみると,Gemfile.lock の記述と(あなたの環境に)インストールされている gem(のバージョン)は無関係と言えることが分かります。
Gemfile.lock は,「そのプロジェクトにおいて現時点で使うことになっている gem(のバージョン)」が記述されている,と考えればいいと思います。

次に,よくある誤解が

  • Gemfile.lock が存在する場合,bundle install すると,Gemfile.lock に従って gem がインストールされる。

です。
わりと正しいのですが,既にインストールされている場合はインストールは行われませんし(当たり前),Gemfile.lock に従わないケースすらあります。
それは Gemfile.lock に書かれたバージョンが Gemfile に書かれたバージョンの条件を満たさない場合です。
例えば,Gemfile.lock が 1.0.3 となっているときに,Gemfile のほうを >= 1.1 と書き換えたら,bundle install では 1.0.3 は採用されず,>= 1.1 を満たすバージョンが選ばれ,Gemfile.lock は書き換えられることになります。

Gemfile と Gemfile.lock の関係はちょっぴりだけ複雑です。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4