Overview
REPL Configuration in Ruby centers on customizing the Interactive Ruby (IRB) environment and alternative REPLs like Pry. Ruby's standard IRB provides extensive configuration options through initialization files, runtime settings, and programmatic configuration APIs. The configuration system controls prompt appearance, command history, auto-completion behavior, output formatting, and workspace context.
IRB reads configuration from .irbrc
files located in the user's home directory or current working directory. The configuration system uses Ruby code directly, allowing complex customization logic and integration with external gems. Configuration affects the IRB::Context
object that manages each REPL session's state, workspace, and behavior.
# Basic .irbrc configuration
IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.conf[:SAVE_HISTORY] = 1000
IRB.conf[:AUTO_INDENT] = true
The configuration system operates through the IRB.conf
hash, which stores all settings as key-value pairs. Changes to this hash immediately affect the current session and persist for future sessions when saved in configuration files. The system supports nested configuration objects for complex features like custom prompts and workspace isolation.
# Accessing configuration programmatically
current_config = IRB.conf
puts current_config[:PROMPT_MODE]
# => :DEFAULT
Ruby also supports per-directory configuration through .irbrc
files in project directories, allowing project-specific REPL environments. The configuration loading order follows a hierarchy: system-wide settings, user home directory settings, then local directory settings, with later configurations overriding earlier ones.
Basic Usage
IRB configuration begins with the .irbrc
file, which Ruby executes as normal Ruby code during IRB startup. The most common configurations involve prompt customization, history management, and basic feature toggles.
# ~/.irbrc - Basic configuration
IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.conf[:SAVE_HISTORY] = 2000
IRB.conf[:HISTORY_FILE] = File.expand_path('~/.irb_history')
IRB.conf[:AUTO_INDENT] = true
IRB.conf[:USE_READLINE] = true
Prompt configuration accepts several predefined modes or custom prompt definitions. The :SIMPLE
mode removes line numbers and reduces visual clutter, while :DEFAULT
provides full context information including nesting level and continuation indicators.
# Custom prompt configuration
IRB.conf[:PROMPT][:CUSTOM] = {
:PROMPT_I => "ruby> ", # Normal prompt
:PROMPT_S => "ruby* ", # String continuation
:PROMPT_C => "ruby? ", # Expression continuation
:PROMPT_N => "ruby+ ", # Nested level indicator
:RETURN => "=> %s\n" # Return value format
}
IRB.conf[:PROMPT_MODE] = :CUSTOM
History configuration controls command persistence between sessions. The SAVE_HISTORY
setting determines how many commands to store, while HISTORY_FILE
specifies the storage location. Setting SAVE_HISTORY
to nil
disables history persistence entirely.
# History configuration options
IRB.conf[:SAVE_HISTORY] = 5000
IRB.conf[:HISTORY_FILE] = '/tmp/irb_history'
IRB.conf[:EVAL_HISTORY] = 100 # Number of results to store
Auto-completion behavior controls how IRB responds to tab key presses. The system supports method name completion, constant completion, and filename completion depending on the context. Disabling readline removes completion functionality but improves compatibility with some terminal environments.
# Completion and editing configuration
IRB.conf[:USE_READLINE] = true
IRB.conf[:USE_TRACER] = false
IRB.conf[:IGNORE_SIGINT] = false
IRB.conf[:IGNORE_EOF] = false
IRB supports workspace isolation through context configuration. Each IRB session operates within a specific binding context, which determines variable accessibility and method resolution. The default context uses the main object, but custom contexts allow sandbox environments and isolated evaluation spaces.
Advanced Usage
Advanced REPL configuration involves custom command definition, startup hooks, output formatting customization, and integration with external tools. These configurations enable sophisticated development workflows and personalized debugging environments.
Custom commands extend IRB functionality beyond Ruby evaluation. Commands register through the IRB::ExtendCommandBundle
module and appear as methods within the REPL session. Command definitions support parameters, help text, and complex logic integration.
# Custom command definition in .irbrc
module IRB::ExtendCommandBundle
def time_eval(statement)
start_time = Time.now
result = eval(statement)
elapsed = Time.now - start_time
puts "Execution time: #{elapsed.round(4)}s"
result
end
end
# Usage: time_eval "sleep 1; 42"
Startup hooks execute arbitrary Ruby code during IRB initialization, enabling environment preparation, gem loading, and utility method definition. Hooks run after basic configuration but before the interactive prompt appears, providing a clean setup phase for complex environments.
# Startup hooks and environment setup
if defined?(IRB)
# Load development gems automatically
begin
require 'awesome_print'
IRB.conf[:USE_COLORIZE] = true
rescue LoadError
puts "awesome_print not available"
end
# Define utility methods
def reload!
load __FILE__ if __FILE__ && File.exist?(__FILE__)
end
def clear
system 'clear'
end
end
Output formatting controls how IRB displays evaluation results and error messages. Custom formatting functions receive the result object and context information, enabling specialized display logic for different data types.
# Custom output formatting
IRB.conf[:USE_COLORIZE] = true
class << IRB.conf[:MAIN_CONTEXT].io
alias_method :original_puts, :puts
def puts(*args)
args.each do |arg|
case arg
when Hash
original_puts JSON.pretty_generate(arg)
when Array
original_puts arg.inspect
else
original_puts arg
end
end
end
end
Workspace configuration enables multiple isolated REPL environments within a single session. Each workspace maintains separate variable bindings, method definitions, and context state. This isolation supports testing different code versions and managing complex debugging scenarios.
# Workspace isolation and context management
class CustomWorkspace < IRB::WorkSpace
def initialize(binding = TOPLEVEL_BINDING, name = "custom")
super(binding)
@workspace_name = name
end
def code_around_binding
if @binding && @binding.respond_to?(:source_location)
location = @binding.source_location
"#{@workspace_name}: #{location&.join(':') || 'unknown'}"
else
@workspace_name
end
end
end
# Switch to custom workspace
IRB.conf[:MAIN_CONTEXT].workspace = CustomWorkspace.new(binding, "debug")
Integration with external tools requires careful configuration management and gem compatibility considerations. Popular gems like Pry, awesome_print, and hirb provide enhanced REPL experiences but may conflict with custom configurations or modify default behavior unexpectedly.
# External tool integration
if defined?(Pry)
# Pry configuration fallback
Pry.config.editor = ENV['EDITOR'] || 'vim'
Pry.config.history_file = File.expand_path('~/.pry_history')
elsif defined?(IRB)
# IRB-specific enhancements
IRB.conf[:USE_COLORIZE] = true
IRB.conf[:COMPLETOR] = :type if IRB::VERSION >= "1.4.0"
end
Common Pitfalls
REPL configuration involves several subtle issues around initialization timing, file loading order, and feature compatibility. These problems often manifest as silent failures or unexpected behavior that can be difficult to diagnose.
Configuration file loading follows a specific order that can cause settings to be overwritten unexpectedly. IRB loads system-wide configuration first, then user home directory .irbrc
, and finally local directory .irbrc
files. Later configurations completely replace earlier settings rather than merging them, which can eliminate carefully crafted customizations.
# Problem: Local .irbrc overwrites all previous configuration
# Home ~/.irbrc
IRB.conf[:SAVE_HISTORY] = 5000
IRB.conf[:PROMPT_MODE] = :CUSTOM
IRB.conf[:AUTO_INDENT] = true
# Project .irbrc (overwrites everything above)
IRB.conf[:PROMPT_MODE] = :SIMPLE # Only this setting remains active
# Solution: Preserve existing settings
IRB.conf[:PROMPT_MODE] = :SIMPLE
IRB.conf[:SAVE_HISTORY] ||= 1000 # Preserve if already set
Prompt customization requires understanding IRB's internal state machine and continuation handling. Custom prompts that don't properly handle all prompt types cause display corruption or missing indicators for nested expressions and string continuations.
# Problematic prompt configuration
IRB.conf[:PROMPT][:BROKEN] = {
:PROMPT_I => "> ", # Missing other prompt types
:RETURN => "=> %s\n"
}
# Complete prompt configuration
IRB.conf[:PROMPT][:COMPLETE] = {
:PROMPT_I => "ruby> ", # Normal input
:PROMPT_S => "ruby* ", # String continuation
:PROMPT_C => "ruby? ", # Command continuation
:PROMPT_N => "ruby+ ", # Nested prompt
:RETURN => "=> %s\n", # Return value display
:AUTO_INDENT => true # Maintain indentation
}
History file permissions and location issues cause silent history loss. IRB attempts to write history files without error handling, leading to situations where commands appear to be saved during the session but disappear after restart due to write permission failures or invalid file paths.
# Problematic history configuration
IRB.conf[:HISTORY_FILE] = "/root/.irb_history" # Permission denied
IRB.conf[:SAVE_HISTORY] = 1000
# Robust history configuration with error handling
history_dir = File.expand_path("~/.config/irb")
Dir.mkdir(history_dir) unless Dir.exist?(history_dir)
history_file = File.join(history_dir, "history")
if File.writable?(File.dirname(history_file))
IRB.conf[:HISTORY_FILE] = history_file
IRB.conf[:SAVE_HISTORY] = 1000
else
warn "Cannot write to #{history_file}, history disabled"
IRB.conf[:SAVE_HISTORY] = nil
end
Gem integration conflicts arise when multiple gems attempt to modify the same IRB configuration settings or when gems make assumptions about default configuration values. These conflicts often result in features being disabled or error messages during startup.
# Conflict between gems modifying the same setting
# Gem A sets:
IRB.conf[:USE_READLINE] = false
# Gem B expects:
if IRB.conf[:USE_READLINE]
# This code never executes due to Gem A
setup_completion_features
end
# Defensive configuration approach
original_readline = IRB.conf[:USE_READLINE]
require 'problematic_gem'
IRB.conf[:USE_READLINE] = original_readline if original_readline
Custom command definition scope issues occur when commands reference variables or methods that aren't available in the IRB evaluation context. Commands defined in the configuration file context may not have access to the current session's variables or workspace methods.
# Problem: Command references unavailable variable
my_config = { debug: true }
module IRB::ExtendCommandBundle
def debug_info
puts my_config[:debug] # my_config not available here
end
end
# Solution: Use instance variables or configuration storage
module IRB::ExtendCommandBundle
def debug_info
config = IRB.conf[:CUSTOM_CONFIG] ||= { debug: true }
puts config[:debug]
end
end
IRB.conf[:CUSTOM_CONFIG] = { debug: true }
Reference
Core Configuration Keys
Setting | Type | Default | Description |
---|---|---|---|
:PROMPT_MODE |
Symbol | :DEFAULT |
Active prompt style identifier |
:SAVE_HISTORY |
Integer/nil | 1000 | Number of commands to persist |
:HISTORY_FILE |
String | ~/.irb_history |
History storage file path |
:AUTO_INDENT |
Boolean | true | Enable automatic indentation |
:USE_READLINE |
Boolean | true | Enable readline library features |
:USE_COLORIZE |
Boolean | true | Enable syntax highlighting |
:EVAL_HISTORY |
Integer | nil | Number of results to remember |
:IGNORE_SIGINT |
Boolean | true | Handle Ctrl+C gracefully |
:IGNORE_EOF |
Boolean | false | Handle Ctrl+D behavior |
:ECHO |
Boolean | true | Display evaluation results |
Prompt Configuration Structure
Key | Purpose | Example |
---|---|---|
:PROMPT_I |
Normal input prompt | "irb> " |
:PROMPT_S |
String continuation | "irb* " |
:PROMPT_C |
Command continuation | "irb? " |
:PROMPT_N |
Nested level indicator | "irb+ " |
:RETURN |
Result display format | "=> %s\n" |
:AUTO_INDENT |
Indentation behavior | true |
Predefined Prompt Modes
Mode | Characteristics | Use Case |
---|---|---|
:DEFAULT |
Full context with line numbers | Development debugging |
:SIMPLE |
Clean minimal prompts | Production console work |
:CLASSIC |
Traditional IRB appearance | Legacy compatibility |
:NULL |
No prompts displayed | Automated scripting |
:XMP |
Example mode formatting | Documentation generation |
Configuration File Locations
Priority | Location | Usage |
---|---|---|
1 | /etc/irbrc |
System-wide defaults |
2 | ~/.irbrc |
User personal settings |
3 | ./.irbrc |
Project-specific configuration |
4 | $IRBRC |
Environment variable path |
Context Configuration Methods
Method | Parameters | Returns | Description |
---|---|---|---|
IRB.conf[:MAIN_CONTEXT].workspace |
WorkSpace object | WorkSpace | Current evaluation binding |
IRB.conf[:MAIN_CONTEXT].io |
IO object | IO | Input/output stream handler |
IRB.conf[:MAIN_CONTEXT].echo? |
None | Boolean | Result display status |
IRB.conf[:MAIN_CONTEXT].inspect? |
None | Boolean | Object inspection mode |
Custom Command Definition
# Command registration pattern
module IRB::ExtendCommandBundle
def command_name(parameters = nil)
# Command implementation
result
end
end
# Required method signature for help system
def help_message_for_command_name
"Description of command functionality"
end
Error Handling Constants
Constant | Value | Usage |
---|---|---|
IRB::Abort |
Exception class | Graceful session termination |
IRB::CantChangeBinding |
Exception class | Workspace modification errors |
IRB::CantShiftToMultiIrbMode |
Exception class | Multi-session failures |
Environment Variables
Variable | Effect | Default |
---|---|---|
IRBRC |
Configuration file path | ~/.irbrc |
IRB_USE_READLINE |
Force readline usage | Auto-detect |
IRB_LANG |
Locale for messages | System locale |
Version Compatibility Matrix
Feature | IRB 1.0+ | IRB 1.3+ | IRB 1.4+ |
---|---|---|---|
Type completion | ❌ | ❌ | ✅ |
Multi-line editing | ❌ | ✅ | ✅ |
Syntax highlighting | ✅ | ✅ | ✅ |
Custom completor | ❌ | ❌ | ✅ |
Configuration Validation
# Validate configuration integrity
def validate_irb_config
required_keys = [:PROMPT_MODE, :SAVE_HISTORY, :AUTO_INDENT]
missing = required_keys.reject { |key| IRB.conf.key?(key) }
warn "Missing configuration: #{missing}" unless missing.empty?
# Validate file permissions
if IRB.conf[:HISTORY_FILE] && !File.writable?(File.dirname(IRB.conf[:HISTORY_FILE]))
warn "History file not writable: #{IRB.conf[:HISTORY_FILE]}"
end
end