CrackedRuby logo

CrackedRuby

IRB

Overview

IRB (Interactive Ruby) provides a command-line interface for executing Ruby code interactively. Ruby implements IRB as a REPL that reads user input, evaluates Ruby expressions, prints results, and loops back for more input. The interpreter maintains session state, allowing variable definitions and method declarations to persist across multiple input lines.

The core IRB functionality centers around the IRB module and IRB::Context class. IRB::Context manages the execution environment, variable bindings, and configuration settings for each IRB session. The IRB::WorkSpace class handles the binding context where code execution occurs, while IRB::Irb manages the main read-eval-print loop.

IRB supports multi-line input detection, automatic indentation, syntax highlighting, and command history. The interpreter can evaluate complex expressions spanning multiple lines, automatically detecting incomplete statements and prompting for continuation.

# Starting IRB
require 'irb'
IRB.start

# Multi-line expression handling
irb> def calculate(x, y)
irb*   x + y
irb* end
# => :calculate

irb> calculate(5, 3)
# => 8

IRB integrates with Ruby's object inspection system, using inspect methods to display return values. The interpreter handles both successful evaluations and exceptions, displaying error information while maintaining session continuity.

# Object inspection in IRB
irb> [1, 2, 3].map { |n| n * 2 }
# => [2, 4, 6]

# Exception handling
irb> 1 / 0
# ZeroDivisionError: divided by 0

Basic Usage

IRB starts from the command line using the irb command or programmatically through IRB.start. The interpreter displays a prompt indicating readiness for input and shows the current nesting level for multi-line constructs.

# Command line invocation
$ irb

# Programmatic start
require 'irb'
IRB.start

The prompt format indicates the current state: irb> for normal input, irb* for continuation lines within multi-line expressions, and irb:001:0> when line numbering is enabled. The numbers show current line and nesting depth.

Variable assignments persist throughout the session, creating a stateful environment for experimentation and development. IRB evaluates each line as complete Ruby syntax, handling both simple expressions and complex constructs.

irb> name = "Ruby"
# => "Ruby"

irb> greeting = "Hello, #{name}!"
# => "Hello, Ruby!"

irb> greeting.upcase
# => "HELLO, RUBY!"

IRB provides built-in commands prefixed with periods. The help command displays available commands, while exit or quit terminates the session. Commands operate independently of Ruby syntax evaluation.

# Built-in commands
irb> .help    # Display help information
irb> .exit    # Exit IRB session
irb> .quit    # Alternative exit command

Method definitions span multiple lines with automatic indentation detection. IRB recognizes incomplete method definitions and continues prompting until the definition completes with the end keyword.

irb> class Calculator
irb*   def initialize
irb*     @result = 0
irb*   end
irb*   
irb*   def add(value)
irb*     @result += value
irb*   end
irb* end
# => :add

irb> calc = Calculator.new
# => #<Calculator:0x... @result=0>

IRB handles require statements and module loading, making external libraries available within the interactive session. Loaded code becomes part of the session environment.

irb> require 'json'
# => true

irb> JSON.parse('{"key": "value"}')
# => {"key"=>"value"}

Advanced Usage

IRB configuration occurs through the IRB.conf hash, allowing customization of prompts, evaluation settings, and display options. Configuration changes affect the current session immediately or can be set in initialization files for persistent preferences.

# Customizing prompts
IRB.conf[:PROMPT][:CUSTOM] = {
  :PROMPT_I => "ruby> ",    # Normal prompt
  :PROMPT_S => "ruby* ",    # String continuation
  :PROMPT_C => "ruby* ",    # Expression continuation
  :RETURN => "=> %s\n"      # Return value format
}
IRB.conf[:PROMPT_MODE] = :CUSTOM

The workspace concept allows IRB to operate within different object contexts. IRB::WorkSpace.new creates a new binding context, while irb method invocation on objects starts nested IRB sessions within that object's context.

class MyClass
  def initialize
    @value = 42
  end
  
  def debug_here
    binding.irb  # Start IRB in this object's context
  end
end

obj = MyClass.new
obj.debug_here
# Now in IRB within obj's context
# @value is accessible directly

IRB supports multiple simultaneous contexts through job management. The jobs command lists active IRB contexts, while fg and kill commands manage context switching and termination.

# Starting multiple contexts
irb> irb :context1
# Starts new context

# In another terminal or after returning
irb> jobs
# => #0->irb :context1
irb> fg 0  # Switch to context 0

Subsession creation allows temporary exploration within specific object scopes without losing the main session state. The irb method called on any object creates a subsession bound to that object's singleton class.

irb> str = "example"
# => "example"

irb> str.irb
# Enters subsession within str object
# 'self' now refers to the string object

Completion customization extends IRB's tab-completion capabilities. The IRB::InputCompletor module handles completion logic, supporting method name completion, constant completion, and file path completion.

# Custom completion proc
IRB.conf[:COMPLETOR] = proc do |input|
  # Custom completion logic
  case input
  when /^custom_/
    ['custom_method1', 'custom_method2']
  else
    IRB::InputCompletor.complete(input)
  end
end

Command extension allows adding custom commands to IRB through command objects. Commands integrate with the built-in command system and accept arguments like standard IRB commands.

class TimestampCommand < IRB::Command::Base
  category "Context"
  description "Show current timestamp"
  
  def execute(arg)
    puts Time.now.strftime("%Y-%m-%d %H:%M:%S")
  end
end

IRB::Command.register(:timestamp, TimestampCommand)

History management controls command history persistence and searching. IRB maintains history across sessions when configured with history file settings and supports history searching with reverse-search capabilities.

# History configuration
IRB.conf[:HISTORY_FILE] = "~/.irb_history"
IRB.conf[:SAVE_HISTORY] = 1000

# History operations available during session
# Ctrl-R for reverse history search
# Up/Down arrows for history navigation

Common Pitfalls

Variable scope confusion occurs when mixing local variables, instance variables, and constants within IRB sessions. IRB maintains a top-level binding where local variables persist, but instance variables belong to the main object context.

# Local variables persist in IRB
irb> local_var = "persists"
# => "persists"

# Instance variables belong to main
irb> @instance_var = "main object"
# => "main object"

# In method definitions, scope differs
irb> def test_scope
irb*   puts local_var  # NameError: local_var not accessible
irb* end

Multi-line input detection can fail with complex expressions containing embedded strings or comments. IRB's parser sometimes misinterprets incomplete expressions, leading to premature evaluation or continued prompting when input is complete.

# Problematic multi-line with strings
irb> text = "This is a
# IRB treats this as incomplete, continues prompting
# even when string should end

# Workaround: explicit line continuation
irb> text = "This is a" \
irb*        " complete string"
# => "This is a complete string"

Method redefinition warnings appear repeatedly in IRB sessions when redefining methods during development. IRB evaluates each method definition as new code, triggering Ruby's warning system for method redefinition.

# First definition
irb> def sample_method
irb*   "first version"
irb* end
# => :sample_method

# Redefinition triggers warning
irb> def sample_method
irb*   "second version"
irb* end
# warning: previous definition of sample_method was here
# => :sample_method

# Suppress warnings during development
irb> $VERBOSE = nil

Binding context confusion occurs when switching between different object contexts within IRB sessions. Variables and methods available in one context may not exist in another, leading to unexpected NameError exceptions.

class Example
  def initialize
    @data = "example data"
  end
  
  def enter_irb
    binding.irb
  end
end

# In main IRB context
irb> obj = Example.new
irb> local_variable = "main context"

# Switching to object context
irb> obj.enter_irb
# Now in Example instance context
# local_variable not accessible here
# @data is accessible

Output truncation happens with large objects or deeply nested structures. IRB uses inspect methods for display, which may produce overwhelming output for complex objects. The output becomes unreadable for large data structures.

# Large array output overwhelms terminal
irb> large_array = (1..1000).to_a
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ... (truncated)]

# Custom inspect for cleaner output
class LargeData
  def initialize(data)
    @data = data
  end
  
  def inspect
    "#<LargeData size=#{@data.size}>"
  end
end

irb> LargeData.new((1..1000).to_a)
# => #<LargeData size=1000>

Exception handling during method definition can leave IRB in inconsistent states. Syntax errors or exceptions within method definitions may cause IRB to continue expecting input even after error occurrence.

# Syntax error in method definition
irb> def broken_method
irb*   if true
irb*     puts "missing end"
irb* end
# SyntaxError: unexpected end

# IRB may still expect more input
# Use Ctrl-C to reset input state

Tab completion interference occurs when custom completion procs conflict with built-in completion. Overly broad custom completion can override useful built-in method and constant completion, reducing productivity.

# Problematic completion override
IRB.conf[:COMPLETOR] = proc do |input|
  # This completely replaces built-in completion
  ['only_custom_option']
end

# Better: augment existing completion
original_completor = IRB.conf[:COMPLETOR]
IRB.conf[:COMPLETOR] = proc do |input|
  custom_completions = []
  if input.start_with?('my_')
    custom_completions = ['my_method1', 'my_method2']
  end
  
  custom_completions + original_completor.call(input)
end

Reference

Core Classes and Modules

Class/Module Purpose Key Methods
IRB Main module containing IRB functionality start, conf, version
IRB::Context Execution context management evaluate, inspect, prompt
IRB::WorkSpace Binding management for code execution binding, main
IRB::Irb Main interpreter loop implementation run, signal_handle

Configuration Options

Option Type Default Description
:AUTO_INDENT Boolean true Automatic indentation for multi-line input
:BACK_TRACE_LIMIT Integer 16 Number of backtrace lines to display
:ECHO Boolean true Display return values
:HISTORY_FILE String nil Path to history file
:IGNORE_EOF Boolean false Ignore EOF (Ctrl-D) for exit
:IGNORE_SIGINT Boolean true Ignore SIGINT (Ctrl-C)
:LOAD_MODULES Array [] Modules to load on startup
:PROMPT_MODE Symbol :DEFAULT Active prompt configuration
:SAVE_HISTORY Integer nil Number of history lines to save
:USE_COLORIZE Boolean true Enable syntax highlighting
:USE_AUTOCOMPLETE Boolean true Enable tab completion
:VERBOSE Boolean nil Verbose output mode

Built-in Commands

Command Arguments Description
.help [command] Display help information or command-specific help
.exit [code] Exit IRB with optional exit code
.quit [code] Alias for exit command
.irb_info None Display IRB version and configuration
.jobs None List active IRB contexts
.fg job_id Switch to specified job context
.kill job_id Terminate specified job context

Prompt Configuration

Prompt Type Symbol Description
Normal Input :PROMPT_I Standard input prompt
String Continuation :PROMPT_S Inside unclosed string literal
Expression Continuation :PROMPT_C Inside unclosed expression
Return Format :RETURN Format string for return values

Default Prompt Modes

Mode Style Example
:DEFAULT Simple format irb>
:CLASSIC Traditional style irb(main):001:0>
:SIMPLE Minimal prompt >>
:INF_RUBY Inf-ruby compatible ruby>
:XMP Example mode No prompt, shows code with results

Exception Classes

Exception Inheritance Usage
IRB::Abort Interrupt IRB session termination
IRB::LoadAbort LoadError Failed module loading during startup

Completion Types

Completion Trigger Examples
Method completion Object followed by . "string".up[TAB]upcase
Constant completion Capitalized identifier Tim[TAB]Time
File completion Path-like strings require "./li[TAB]./lib/
Variable completion Variable prefixes @inst[TAB]@instance_var

Startup Files

File Location Purpose Load Order
~/.irbrc User-specific configuration 1st
./.irbrc Project-specific configuration 2nd
Environment variable IRBRC Custom configuration file Alternative

Signal Handling

Signal Default Behavior Configuration
SIGINT (Ctrl-C) Interrupt current input :IGNORE_SIGINT
SIGTERM Terminate IRB session Not configurable
SIGQUIT (Ctrl-\) Force quit with backtrace Not configurable
EOF (Ctrl-D) Exit IRB session :IGNORE_EOF