В поставку Ruby входит утилита gem, через которую ставятся, обновляются и удаляются зависимости. В целом gem — это часть RubyGems, механизма управления библиотеками или пакетами в Ruby.
Каждая библиотека в Ruby называется гемом. Программисты так и говорят: "Давайте использовать вот этот гем". Список всех гемов можно найти:
- На сайте RubyGems
- В модерируемом каталоге RubyToolbox, в котором гемы разбиты по категориям
Как и у любого пакетного менеджера, у RubyGems есть пути, по которым можно ставить библиотеки и менять переменные окружения. Такое может понадобиться при работе с Docker.
Чтобы увидеть настройки RubyGems, нужно набрать команду gem env
:
# Очень помогает в отладке
RubyGems Environment:
- RUBYGEMS VERSION: 3.2.32
- RUBY VERSION: 3.0.3 (2021-11-24 patchlevel 157) [x86_64-darwin21]
- INSTALLATION DIRECTORY: /Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0
- USER INSTALLATION DIRECTORY: /Users/myname/.gem/ruby/3.0.0
- RUBY EXECUTABLE: /Users/myname/.asdf/installs/ruby/3.0.3/bin/ruby
- GIT EXECUTABLE: /usr/local/bin/git
- EXECUTABLE DIRECTORY: /Users/myname/.asdf/installs/ruby/3.0.3/bin
- SPEC CACHE DIRECTORY: /Users/myname/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /Users/myname/.asdf/installs/ruby/3.0.3/etc
- RUBYGEMS PLATFORMS:
- ruby
- x86_64-darwin-21
- GEM PATHS: # Пути по которым происходит установка гемов
- /Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0
- /Users/myname/.gem/ruby/3.0.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /Users/myname/.asdf/installs/ruby/3.0.3/bin
- /usr/local/sbin
- /Users/myname/.asdf/shims
- /Users/myname/.asdf/bin
- /usr/local/bin
- /usr/bin
- /bin
- /usr/sbin
- /sbin
Обратите внимание на GEM PATHS. В Ruby все гемы по умолчанию ставятся в общую директорию, а не в директорию проекта. То есть неважно откуда мы выполняем команду установки, все гемы будут лежать в одном месте. Тогда возникает вопрос, как RubyGems работает с разными версиями одной и той же библиотеки? Очень просто, имя директории гема включает в себя и версию:
ls /Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems
aasm-5.2.0 omniauth-2.0.4
abbrev-0.1.0 omniauth-github-2.0.0
actioncable-6.1.4.1 omniauth-oauth2-1.7.2
actionmailbox-6.1.4.1 omniauth-rails_csrf_protection-1.0.0
actionmailer-6.1.4.1 open-uri-0.1.0
actionpack-6.1.4.1 open3-0.1.1
actionpack-7.0.0 openssl-2.2.1
actiontext-6.1.4.1 optparse-0.1.1
actionview-6.1.4.1 orm_adapter-0.5.0
Несколько примеров того, как работать с гемами:
# Линтер на Ruby
# По умолчанию установка происходит в системные директории
gem install rubocop
Fetching rubocop-1.25.1.gem
Fetching parser-3.1.1.0.gem
Successfully installed parser-3.1.1.0
Successfully installed rubocop-1.25.1
Parsing documentation for parser-3.1.1.0
Installing ri documentation for parser-3.1.1.0
Parsing documentation for rubocop-1.25.1
Installing ri documentation for rubocop-1.25.1
Done installing documentation for parser, rubocop after 18 seconds
2 gems installed # 2 потому что с зависимостями
rubocop -v
1.25.1
# HTTP-клиент
# https://github.com/lostisland/faraday
gem install faraday
# Тут вывод
2 gems installed
irb # Проверяем в repl
# Имя для включения почти всегда соответствует названию гема
irb(main):001:0> require 'faraday'
=> true
irb(main):002:0> response = Faraday.get('https://ru.hexlet.io')
=>
#<Faraday::Response:0x00007f8a3012bf08
...
irb(main):003:0> response.status
=> 200
RubyGems модифицирует пути загрузки, по которым инструкция require
производит поиск Ruby-кода. Каждый раз когда выполняется require
, RubyGems всего лишь добавляет директорию lib гема в этот список путей.
irb(main):002:0> $LOAD_PATH
=>
["/Users/kirillmokevnin/.asdf/plugins/ruby/rubygems-plugin",
"/Users/kirillmokevnin/.asdf/installs/ruby/3.0.3/lib/ruby/site_ruby/3.0.0",
"/Users/kirillmokevnin/.asdf/installs/ruby/3.0.3/lib/ruby/site_ruby",
"/Users/kirillmokevnin/.asdf/installs/ruby/3.0.3/lib/ruby/vendor_ruby/3.0.0",
"/Users/kirillmokevnin/.asdf/installs/ruby/3.0.3/lib/ruby/vendor_ruby",
"/Users/kirillmokevnin/.asdf/installs/ruby/3.0.3/lib/ruby/3.0.0"]
irb(main):003:0> require 'faraday' # Включение
irb(main):004:0> $LOAD_PATH
=> # Обратите внимание на пути до faraday
["/Users/myname/.asdf/plugins/ruby/rubygems-plugin",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/faraday-net_http-2.0.1/lib",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/ruby2_keywords-0.0.5/lib",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/faraday-2.2.0/lib",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/gems/3.0.0/gems/faraday-2.2.0/spec/external_adapters",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/site_ruby/3.0.0",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/site_ruby",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/vendor_ruby/3.0.0",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/vendor_ruby",
"/Users/myname/.asdf/installs/ruby/3.0.3/lib/ruby/3.0.0"]
Все это так же работает и через файлы.
# index.rb
require 'faraday'
response = Faraday.get('https://ru.hexlet.io')
puts response.status
И запуск:
ruby index.rb
200
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.