skip to content

RubyGems

RubyGems is Ruby's package format, the gem command and the rubygems.org registry: it installs gems into gem paths and builds and publishes new ones. Asked to see where it stops and Bundler starts.

on this pageshow

explore

questions

11

In RubyGems 4, what do gem install, gem list, gem update and gem uninstall do, and does gem update remove the older version?

level: juniorimportance: must knowfreq 62%

answer

  1. versions live side by side
  2. the cleanup command
  3. -v takes a version requirement
  4. Select gem to uninstall prompt
  5. --system is a different job

basics

~20 s

gem install puts a gem and its runtime dependencies into GEM_HOME, gem list shows installed versions, gem update adds the newest version beside the old one, and gem uninstall removes a version. Only gem cleanup or uninstall deletes old versions.

solid answer

~40 s

`gem install rack` fetches the gem from the configured source (rubygems.org by default), installs it and its runtime dependencies into `GEM_HOME`, and writes wrapper executables into the bin directory; `-v '~> 3.2'` picks a version and `-N` skips the ri docs installed by default. `gem list rack` shows every locally installed version, marking a default gem as `default: x.y.z`. `gem update rack` installs the newest release **alongside** the existing one; it never deletes the old version, which is what `gem cleanup` is for. `gem uninstall rack` removes one version, prompts with `Select gem to uninstall:` when several are installed, and asks before removing a gem another gem depends on. `gem update --system` is separate: it updates RubyGems itself.

code

bash · 6 lines
bash
gem install rack -v '~> 3.2' -N   # newest 3.x at or above 3.2, no docs
gem list rack -e                   # rack (3.2.7, 2.2.x ...)
gem update rack                    # adds the newest rack beside the others
gem cleanup rack                   # removes old versions nothing depends on
gem uninstall rack -v 3.2.7        # remove exactly one version
gem update --system                # update RubyGems itself

go deeper

for a junior

Know the four verbs and their direction: install adds, list shows every version, update adds the newest beside the old, uninstall removes. Remember gem cleanup is what actually deletes old versions.

for a middle

Explain why versions accumulate, how gem cleanup decides what to remove, and why uninstall prompts. Mention that -v takes a requirement and that gem list marks default gems.

for a senior

Show you keep machines tidy without breaking dependents: cleanup scoped to GEM_HOME, uninstall -v for exact removals, and gem update --system handled separately from gem upgrades.

for a principal

Argue when hand-run gem commands are acceptable at all, versus letting Bundler and a lockfile own every application gem, and who owns RubyGems upgrades on shared build images.

## What the gem command is **RubyGems** is Ruby's package manager, and it ships with every Ruby 4.0 install (Ruby 4.0.7 carries RubyGems 4.0.20; the current release is 4.0.21). A **gem** is a packaged Ruby library: code, a **specification** (name, version, dependencies, files) and optionally executables. The `gem` command is its command-line front end, and four subcommands cover everyday use. ## gem install `gem install NAME` resolves the newest version that satisfies any requirement you give, downloads it from the configured source (rubygems.org unless you changed `gem sources`), and installs it **with its runtime dependencies** into the directory RubyGems calls `GEM_HOME`. - `-v, --version` takes a **requirement**, not just a number: `gem install rack -v '~> 3.2'` or `-v 3.2.7`. - `-N` / `--no-document` skips documentation; the default is `--document=ri`. - `--user-install` writes to your home directory instead of `GEM_HOME`. - `--conservative` leaves an installed version alone when it already meets the requirement. - `gem i` is an alias for `gem install`. For every executable the gem declares, RubyGems writes a small **wrapper script** into the executable directory, so `rake` or `rackup` run from your shell. ## gem list `gem list` prints local gems, with **every installed version** of each on one line. The argument is a regular expression, so `gem list rack` also shows `rack-session` and `rack-protection`; add `-e` for an exact name. A version that shipped with Ruby is labelled `default:` in the list, `-d` adds details such as the install path, and `--remote` asks the server instead of the local disk. The old `gem query` command was **removed in RubyGems 4.0**; `gem list` and `gem search` (remote by default) replace it. ## gem update `gem update NAME` installs the newest version of that gem; with no name it updates every installed gem. The key fact, stated in the command's own help: **the update command does not remove the previous version.** RubyGems keeps versions side by side on purpose, because another gem or script may still need the old one. Removing old versions is a separate, explicit step: 1. `gem cleanup NAME` removes older versions from `GEM_HOME` that no installed gem needs to meet a dependency. 2. With no name, `gem cleanup` does that for every gem in `GEM_HOME`. 3. It never touches gems installed elsewhere in `GEM_PATH`, and it skips default gems. ## gem uninstall `gem uninstall NAME` removes installed versions: - With several versions installed it shows a `Select gem to uninstall:` menu that includes `All versions`; `-a` removes them all, `-v` names one. - If another installed gem depends on the one you remove, it asks for confirmation; `-I` (`--ignore-dependencies`) skips that check. - `-x` removes the gem's executables without asking. - A **default gem** (one that ships inside Ruby, such as json) cannot be removed: RubyGems prints that it `cannot be uninstalled because it is a default gem`. ## gem update --system is not gem update | Command | Changes | |---|---| | `gem update` | every installed gem, to its newest version | | `gem update rack` | only rack, newest version added beside the old | | `gem update --system` | RubyGems itself (and its default Bundler) | `gem update --system` installs the `rubygems-update` gem and runs its `setup.rb`, replacing the RubyGems library that Ruby loads; it refuses gem names (`Gem names are not allowed with the --system option`), accepts an optional target version, and Ruby distributors can disable it. It does not upgrade the Ruby interpreter. ## Version requirements on the command line The `-v` flag of `gem install` and `gem uninstall` takes a **requirement**, built from the operators `=`, `!=`, `>`, `<`, `>=`, `<=` and `~>`: - `-v 3.2.7` means exactly that version. - `-v '>= 3.0'` means any version from 3.0 up; the newest one available wins. - `-v '~> 3.2'` means at least 3.2 but below 4.0, and `-v '~> 3.2.0'` means at least 3.2.0 but below 3.3. Quote the requirement so the shell does not treat `>` as a redirect. `-v` applies to one gem only: with several gems RubyGems stops with `Can't use --version with multiple gems` and suggests the `name:requirement` form instead, as in `gem install 'rack:3.2.7' 'rake:~>13.3'` (the same form works for `gem uninstall`). ## Common mistakes - Expecting `gem update` to free disk space: it only ever adds versions, so a machine updated for years can hold many copies of the same gem until someone runs `gem cleanup`. - Uninstalling the "wrong" version by accepting the default answer in the `Select gem to uninstall:` menu instead of passing `-v`. - Running `gem update` with no arguments on a shared machine and upgrading every gem at once, which can break scripts that relied on the older versions being newest. - Expecting `gem update --system` to change the Ruby version reported by `ruby -v`: it only replaces RubyGems. ## Everyday habits - Read `gem list NAME` before blaming "the wrong version": several versions installed at once is normal. - Treat `gem cleanup` as the uninstall step `gem update` deliberately left out. - An application's full gem set belongs to Bundler and its lockfile, not to hand-run `gem install` commands.

  • Why does RubyGems keep the old version after gem update instead of replacing it?
    Several versions of a gem may be needed at once on one machine: another installed gem can depend on the older release, and a script can pin it. Deleting it silently could break those. RubyGems therefore installs the new version beside the old and leaves removal to `gem cleanup`, which only deletes versions no installed gem needs, or to an explicit `gem uninstall -v`.
  • What does gem update --system change, and what does it not change?
    It updates RubyGems itself: it installs the `rubygems-update` gem at the target version and runs that gem's `setup.rb`, which also installs the matching Bundler as a default gem. It does not update your other gems, it rejects gem names as arguments, and it never upgrades the Ruby interpreter; Ruby distributors can also disable it in favour of their own packages.
  • How do you see where a gem is installed and which file a require would load from it?
    `gem list rack -d` prints the details, including the directory each version is installed in. `gem contents rack` lists the gem's files, and `gem which rack` prints the path of the file that `require "rack"` would load. `gem env` shows the directories RubyGems installs into and searches.

saying these in an interview costs you the question

  • Believes gem update deletes the previous version automatically
  • Thinks gem update --system upgrades every installed gem
  • Expects gem update --system to upgrade the Ruby interpreter
  • Still reaches for gem query, removed in RubyGems 4.0
  • Assumes gem uninstall can remove default gems like json
  • Thinks -v on gem install accepts only an exact version number
open as a page

In RubyGems, what is a .gemspec file, which fields must it set, and what does gem build produce from it?

level: juniorimportance: must knowfreq 52%

basics

~10 s

A .gemspec is Ruby code that builds a Gem::Specification: name, version, summary, authors, files, require_paths and dependencies. gem build validates it and packages the listed files into name-version.gem, the file gem push uploads.

open as a page

In RubyGems, what is the difference between GEM_HOME and GEM_PATH, and where does gem install --user-install put gems?

level: middleimportance: must knowfreq 45%

basics

~10 s

GEM_HOME is the single directory gem install writes into; GEM_PATH is the list of directories RubyGems searches for installed gems, and GEM_HOME is always part of it. --user-install writes to Gem.user_dir, such as ~/.gem/ruby/4.0.0.

open as a page

In a RubyGems gemspec, what is the difference between add_dependency and add_development_dependency, and what goes wrong if you mix them up?

level: middleimportance: must knowfreq 55%

basics

~20 s

add_dependency declares a runtime dependency, installed and activated with your gem. add_development_dependency declares a tool needed only to work on the gem; gem install skips it unless --development is given, and it is never activated.

open as a page

When you publish version 1.0 of a gem with gem push, how do RubyGems API keys, MFA and --otp work, and which gemspec metadata hardens the release?

level: seniorimportance: must knowfreq 42%

basics

~20 s

gem push uploads a built .gem using an API key from gem signin or GEM_HOST_API_KEY. With MFA enabled, the server demands a one-time code passed via --otp or GEM_HOST_OTP_CODE. Metadata rubygems_mfa_required and allowed_push_host harden pushes.

open as a page

In Ruby 4.0, what is the difference between a default gem and a bundled gem, and what does gem uninstall do to each?

level: middleimportance: should knowfreq 36%

basics

~20 s

Both ship with Ruby 4.0. Default gems such as json and bundler are standard library: gem uninstall refuses them, but a newer copy can sit beside them. Bundled gems such as rake and minitest are ordinary preinstalled gems uninstall removes.

open as a page

In Ruby, how can one laptop keep rack 2.2 and rack 3.2 installed for two projects, and how does Kernel#gem choose one per process?

level: middleimportance: should knowfreq 34%

basics

~20 s

RubyGems installs each version in its own name-version directory, so both racks coexist. A process activates one version per gem: Kernel#gem("rack", "~> 2.2") called before require pins the newest matching version; otherwise require activates the highest installed.

open as a page

In a RubyGems gemspec, what do files, require_paths and required_ruby_version control, and why can a freshly published gem fail with LoadError?

level: middleimportance: should knowfreq 40%

basics

~20 s

files lists exactly what goes into the .gem, require_paths names the directories added to the load path on activation (default lib), and required_ruby_version filters installs. A file missing from files, or code outside require_paths, raises LoadError after install.

open as a page

In RubyGems, what makes a version such as 1.0.0.rc1 a prerelease, and how do users install one before the final 1.0.0?

level: middleimportance: should knowfreq 28%

basics

~10 s

A RubyGems version containing a letter, such as 1.0.0.rc1 or 1.0.0.beta.2, is a prerelease and sorts below 1.0.0. gem install ignores prereleases unless given --prerelease or a -v requirement naming one.

open as a page

A Ruby script without Bundler fails on require "sinatra" with Gem::ConflictError: sinatra 4.2.1 cannot activate because an active rack 2.2 conflicts with rack (>= 3.0.0, < 4). What happened, and how do you fix it?

level: seniorimportance: should knowfreq 24%

basics

~20 s

Something activated rack 2.2 earlier in the process, and sinatra 4.2.1 declares rack >= 3.0.0, < 4. Activation checks each runtime dependency against Gem.loaded_specs and raises Gem::ConflictError. Fix the earlier activation, or let Bundler resolve the whole set.

open as a page

You pushed hue_palette 1.0.0 to rubygems.org and it contains an API token by mistake. What does gem yank do, what does it not undo, and what do you do next?

level: seniorimportance: should knowfreq 32%

basics

~20 s

gem yank hue_palette -v 1.0.0 removes that version from the rubygems.org index so new installs cannot resolve it. It cannot recall copies already downloaded, so revoke the leaked token first, yank, and ship a fixed 1.0.1.

open as a page