環境。
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