/flags/ruby/ruby-r-require-library
ruby -r and -I: require a library and add to the load path from the command line
- 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:
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
| Option | Effect | Equivalent in code or environment |
|---|---|---|
| -r lib (or -rlib) | Require lib before running | require "lib" at the top |
| -I dir (or -Idir) | Prepend dir to $LOAD_PATH; repeatable | $LOAD_PATH.unshift "dir" |
| RUBYLIB=dir1:dir2 | Add directories to $LOAD_PATH for every process | -I for all commands |
| RUBYOPT="-rlib" | Pass options to every Ruby process | Used by bundle exec for bundler/setup |
| -rbundler/setup | Load only the gems from Gemfile.lock | require "bundler/setup" |
Typical uses
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
-rtakes a library name as used byrequire, not a path with.rb(although-r./file.rbwith a relative path also works).- The current directory has not been in the load path since Ruby 1.9.2. Use
require_relativein files and-I.on the command line. -rruns 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-Ipaths 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.