Skip to content

/flags/ruby/ruby-r-require-library

ruby -r and -I: require a library and add to the load path from the command line

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
Ruby
command
ruby
flag
-r library, -I directory
default
load path: Ruby's standard library and gem directories only (not the current directory)

ruby -rjson app.rb requires the json library before the script runs, exactly as if the script started with require "json". ruby -Ilib app.rb adds the lib directory to the front of $LOAD_PATH, so require "my_gem" finds lib/my_gem.rb. Together, ruby -Ilib -rmy_gem -e '...' loads your own code for a quick experiment. A library that cannot be found fails with cannot load such file (LoadError).

-r, -I and the error

The example runs the official CRuby 3.4 build for WebAssembly from the ruby.wasm project, as a regular command-line program with Node.js; ruby below is that interpreter:

bash
curl -sSfLO https://github.com/ruby/ruby.wasm/releases/download/2.8.1/ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
echo "ccda86a375a4fe09849846d3b03a370172a4902a0c571087f48457388a2762c7  ruby-3.4-wasm32-unknown-wasip1-full.tar.gz" | sha256sum -c --quiet
tar xzf ruby-3.4-wasm32-unknown-wasip1-full.tar.gz
cat > ruby.mjs <<'JS'
// Minimal "ruby" command: runs the official CRuby 3.4 WASI build with the given arguments
import fs from "node:fs";
import { WASI } from "node:wasi";
const root = "ruby-3.4-wasm32-unknown-wasip1-full/usr";
const wasi = new WASI({ version: "preview1", args: ["ruby", "--disable-gems", ...process.argv.slice(2)], env: {}, preopens: { "/usr": root, ".": "." }, returnOnExit: true });
const mod = await WebAssembly.compile(fs.readFileSync(`${root}/local/bin/ruby`));
process.exitCode = wasi.start(await WebAssembly.instantiate(mod, wasi.getImportObject()));
JS
ruby() { node --no-warnings ruby.mjs "$@"; }
mkdir -p lib
echo 'module Greeter; def self.hi(name) = "hi #{name}"; end' > lib/greeter.rb
echo "== -r with standard libraries"
ruby -rjson -rset -e 'p Set[1, 2].include?(2), JSON.parse("[1, 2]")'
echo "== own library without -I"
ruby -e 'require "greeter"' 2>&1 | head -1; echo "exit: ${PIPESTATUS[0]}"
echo "== with -Ilib"
ruby -Ilib -rgreeter -e 'puts Greeter.hi("ruby")'
echo "== -r with a missing library"
ruby -rnosuch -e 'puts 1' 2>&1; echo "exit: $?"

Output

== -r with standard libraries
true
[1, 2]
== own library without -I
-e:1:in 'Kernel#require': cannot load such file -- greeter (LoadError)
exit: 1
== with -Ilib
hi ruby
== -r with a missing library
-e:in 'Kernel#require': cannot load such file -- nosuch (LoadError)
exit: 1

Standard libraries such as json and set are on the default load path. Your own lib folder is not, so the plain require fails until -Ilib adds it. A missing -r library stops Ruby before the code runs, with exit status 1.

Options and equivalents

OptionEffectEquivalent in code or environment
-r lib (or -rlib)Require lib before runningrequire "lib" at the top
-I dir (or -Idir)Prepend dir to $LOAD_PATH; repeatable$LOAD_PATH.unshift "dir"
RUBYLIB=dir1:dir2Add directories to $LOAD_PATH for every process-I for all commands
RUBYOPT="-rlib"Pass options to every Ruby processUsed by bundle exec for bundler/setup
-rbundler/setupLoad only the gems from Gemfile.lockrequire "bundler/setup"

Typical uses

bash
ruby -Ilib -Itest test/greeter_test.rb       # run one Minitest file, as rake test does
ruby -Ilib -rmy_gem -e 'p MyGem::VERSION'     # poke at your gem without installing it
ruby -rbundler/setup app.rb                   # only Gemfile.lock gems, like bundle exec
ruby -rdebug app.rb                           # start under the debug gem (Ruby 3.1+ bundles it)

bundle exec works by setting RUBYOPT=-rbundler/setup for the command it runs; see bundle exec.

Pitfalls

  • -r takes a library name as used by require, not a path with .rb (although -r./file.rb with a relative path also works).
  • The current directory has not been in the load path since Ruby 1.9.2. Use require_relative in files and -I. on the command line.
  • -r runs the library's top-level code before your script, including any output or side effects it has.
  • Gems are found through RubyGems, which Ruby loads by default; with --disable-gems (used only by the wrapper in this example) only the standard library and -I paths are available.

FAQ

Why does require 'mylib' fail although mylib.rb is in the current folder?

The current directory is not in Ruby's load path. Use require_relative 'mylib' inside a file, run ruby -I. app.rb, or require it with a path: require './mylib'.

What is the difference between -r and RUBYOPT=-r?

ruby -rlib affects one command. RUBYOPT=-rlib is read by every Ruby process that inherits the environment, which is how bundle exec loads bundler/setup into child processes.

Is ruby -I the same as RUBYLIB?

Both add directories to $LOAD_PATH. RUBYLIB is an environment variable with a colon-separated list (semicolon on Windows). Directories from -I come before those from RUBYLIB in the load path.

Sources