環境。
OSはmacOS High Sierra(10.13.5)。
Ruby自体のバージョン管理はrbenv(1.1.1)で行う。
rbenvについては以下を参照。
numb86-tech.hatenablog.com
グローバルインストール
RubyではRubyGemsという仕組みを使ってパッケージ管理を行う。扱われる一つ一つのパッケージをgemと呼ぶ。
バージョン1.9以降のRubyにはこの仕組みが標準で入っているため、特に何もしなくてもgemコマンドを使える。
$ gem -v 2.7.6
$ gem install パッケージ名でインストールできる。
インストール先は$ gem environmentで確認できる。
色々と情報が出てくるが、INSTALLATION DIRECTORYがインストール場所。
自分の環境だと/Users/$USER/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0と表示された。
このディレクトリ内のgemsのなかに、インストールしたgemが入っている。
$ ls /Users/$USER/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0 build_info cache doc extensions gems specifications $ ls /Users/$USER/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems (インストール済みのgemがここに表示される)
$ gem listでも一覧を確認できる。
先程のディレクトリに入っていないgemも表示されているが、これは最初からインストールされているgemである。
bigdecimal (default: 1.3.4)のようにdefaultと書かれているものが、これに該当する。
この方法でインストールしたgemは、npmでいうところのグローバルインストールになる。
つまり、どのディレクトリやプロジェクトからでも使うことが出来る。
$ gem listすると*** LOCAL GEMS ***と表示されるが、これはグローバルの対義語ではなく、*** REMOTE GEMS ***の対となるという意味での「ローカル」だと思われる。
Rails のインストール
例として、Railsをグローバルインストールしてみる。
最初に、インストールされていないことを確認。
$ rails -v
Rails is not currently installed on this system. To get the latest version, simply type:
$ sudo gem install rails
You can then rerun your "rails" command.
インストール。
$ gem install rails
インストールされているか確認してみる。
$ ls /Users/$USER/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems | grep rails rails-5.2.0 rails-dom-testing-2.0.3 rails-html-sanitizer-1.0.4 sprockets-rails-3.2.1 $ gem list | grep rails rails (5.2.0) rails-dom-testing (2.0.3) rails-html-sanitizer (1.0.4) sprockets-rails (3.2.1)
インストールできていることを確認できた。
早速Railsを使ってみる。
$ rails -v
Rails is not currently installed on this system. To get the latest version, simply type:
$ sudo gem install rails
You can then rerun your "rails" command.
実行できない。実は、頭にrbenv execを付ける必要がある。
$ rbenv exec rails -v Rails 5.2.0
rbenv execの正確な意味は分かっていないが、「rbenvで管理しているRuby」を明示するような意味らしい。
gemのインストール先のパスが/Users/$USER/.rbenv/以下であることから分かるように、インストールしたgemはrbenvに紐付いている。
そのため、rbenv execが必要なのだろう。
しかし、いちいちrbenv execを付けるのは面倒である。
そのため、付けなくても動作するように設定する。
具体的には、$ rbenv rehashを使えばよい。
$ rbenv rehash $ rails -v Rails 5.2.0
こうすると、どのディレクトリからでもrailsコマンドを使える。
つまり、グローバルインストールされた状態になる。
なお、前述のようにrbenvに紐付いているため、Rubyのバージョンを変えると利用することは出来ない。
他のバージョンのRubyでも利用したい場合は、そのバージョンに切り替えている状態で改めてgem installする。
$ rbenv local 2.5.0 $ rails -v rbenv: rails: command not found The `rails' command exists in these Ruby versions: 2.5.1 $ rbenv local --unset $ rails -v Rails 5.2.0
bundler
グローバルインストールではなくディレクトリ毎にgemをインストールしたい場合は、bundlerというツールを使う。
これ自身もgemの一種であり、これをグローバルインストールしておくとbundleコマンドを使える。
ツールの名前とコマンド名が異なるので注意。
まずはインストール。
$ gem install bundler $ rbenv rehash $ bundle -v Bundler version 1.16.2
bundlerを使ってgemをインストールするにはまず、管理したいディレクトリに移動し、$ bundle initを実行する。
そうするとGemfileというファイルが作られる。
$ bundle init
Writing new Gemfile to /Users/$USER/Documents/tech/rbenv-blog/v3/Gemfile
$ ls
Gemfile
$ cat Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
# gem "rails"
このGemfileに、インストールしたいgemを書いていく。
今回はv3.5.0のsassをインストールしてみる。
--- a/Gemfile +++ b/Gemfile @@ -5,3 +5,4 @@ source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } # gem "rails" +gem "sass", "3.5.0"
この状態でインストールするのだが、必ずpathオプションを指定する。オプションの値は慣例的にvendor/bundleが使われるようだ。
$ bundle install --path=vendor/bundle
こうすると、指定したパス以下にインストールされる。
$ ls vendor/bundle/ruby/2.5.0/gems ffi-1.9.25 rb-fsevent-0.10.3 rb-inotify-0.9.10 sass-3.5.0 sass-listen-3.0.7
$ bundle listで、インストールされているgemを確認できる。
$ bundle list Gems included by the bundle: * bundler (1.16.2) * ffi (1.9.25) * rb-fsevent (0.10.3) * rb-inotify (0.9.10) * sass (3.5.0) * sass-listen (3.0.7)
早速sassを使おうとするが、出来ない。
bundleでインストールしたgemをコマンドラインで使う場合、頭にbundle execを付ける必要がある。
$ sass -v -bash: sass: command not found $ bundle exec sass -v Sass 3.5.0 (Bleeding Edge)
bundle execを省略する方法もあるのだが、それは後述する。
bundle installの結果作られたものとして他に、Gemfile.lockと.bundle/configがある。
Gemfile.lockには、今回インストールしたsassの他に、sassが依存関係にあるgemについてバージョン情報と共に書かれてある。
このファイルがあることで、どの環境で$ bundle installを実行しても同じgemがインストールされ、冪等性が保たれる。
フロントエンドでいうところのpackage-lock.jsonやyarn.lockのようなものだと思う。
.bundle/configの中には、--pathで指定した値が記録されている。
$ cat .bundle/config --- BUNDLE_PATH: "vendor/bundle"
そしてこの情報がある場合、インストールの際にパスを指定する必要がなくなる。
例えば、Gemfileの末尾にgem "foreman"と追記して$ bundle installを実行してみる。
$ ls vendor/bundle/ruby/2.5.0/gems ffi-1.9.25 rb-fsevent-0.10.3 sass-3.5.0 thor-0.19.4 foreman-0.85.0 rb-inotify-0.9.10 sass-listen-3.0.7
明示的に指定しなくてもvendor/bundleにインストールされているのを確認できる。
では、インストール時の指定も.bundle/configでの指定も無い場合は、どうなるのか。
新しくディレクトリを作り、そこで改めて$ bundle initから作業してみる。
$ bundle init Writing new Gemfile to /Users/$USER/Documents/tech/rbenv-blog/v4/Gemfile $ echo 'gem "sass", "3.5.6"' >> Gemfile $ bundle install Fetching gem metadata from https://rubygems.org/............ Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Using bundler 1.16.2 Using ffi 1.9.25 Using rb-fsevent 0.10.3 Using rb-inotify 0.9.10 Using sass-listen 4.0.0 Fetching sass 3.5.6 Installing sass 3.5.6 Bundle complete! 1 Gemfile dependency, 6 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed.
こうすると、そのディレクトリではなく、/Users/$USER/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0にインストールされる。
つまり、グローバルインストールになる。
$ ls -a . .. Gemfile Gemfile.lock $ ls /Users/$USER/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems | grep sass sass-3.5.6 $ gem list | grep sass sass (3.5.6) $ rbenv rehash $ sass -v Ruby Sass 3.5.6
binstubs
上述のように、vendor/bundleにインストールしたgemを使うためには、bundle execをつける必要がある。
これを避けるには、binstubsという、rbenvのプラグインを使う。
まず、~/.rbenv/pluginsに移動。無ければ作る。
そして以下のリポジトリをクローンすればよい。
https://github.com/ianheggie/rbenv-binstubs
$ cd ~/.rbenv/plugins $ git clone https://github.com/ianheggie/rbenv-binstubs.git
あとはbundle installの際に--binstubs=vendor/binとして、このプラグインを使えばよい。
新しいディレクトリを作って試してみる。
$ bundle init Writing new Gemfile to /Users/$USER/Documents/tech/rbenv-blog/v5/Gemfile $ echo 'gem "sass", "3.5.1"' >> Gemfile $ bundle install --path=vendor/bundle --binstubs=vendor/bin Fetching gem metadata from https://rubygems.org/............ Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Using bundler 1.16.2 Fetching ffi 1.9.25 Installing ffi 1.9.25 with native extensions Fetching rb-fsevent 0.10.3 Installing rb-fsevent 0.10.3 Fetching rb-inotify 0.9.10 Installing rb-inotify 0.9.10 Fetching sass-listen 4.0.0 Installing sass-listen 4.0.0 Fetching sass 3.5.1 Installing sass 3.5.1 Bundle complete! 1 Gemfile dependency, 6 gems now installed. Bundled gems are installed into `./vendor/bundle` $ sass -v Sass 3.5.1 (Bleeding Edge)
このマシンには3.5.6がグローバルインストールされているが、それではなくこのディレクトリにインストールした3.5.1を使用していることが分かる。
sassがインストールされていないディレクトリで実行すると、3.5.6を使う。
$ sass -v Ruby Sass 3.5.6