Using irb (Interactive Ruby Shell) for Examples
Tags: ruby, irb, documentation, examples
Published: 2019-06-29 19:37:47

---
title: Using irb (Interactive Ruby Shell) for Examples
published: true
description: How to capture an irb session for use as an example.
tags: ruby, irb, documentation, examples
---
Like most of us, I've usually done code examples thus:

- Display code as highlighted block.
- (Sometimes) display command as highlighted block.
- Display output as highlighted block.

Lately, I've been experimenting with using <code>irb</code>, the Interactive Ruby Shell, to build examples.  In <code>irb</code>, I can show how values change as a program progresses.

To illustrate, I'll use a small Ruby script that does some work on hashes.

<h4>Ruby Session Input</h4>

This code is in a file that will be fed to <code>irb</code> as input.  As the code executes, it uses method <code>Kernel#p</code> to display and re-display values, showing how they have changed:

```ruby
# Create and display two hashes.
h0 = {:a => 0, :b => 1}
p h0
h1 = {:b => 2, :c => 3}
p h1

# Merge the second hash into the first.
h0.merge!(h1)
p h0

# Add an element.
h0.store(:d, 4)
p h0

# Remove an element.
h0.delete(:b)
p h0
```
<h4>Session Output</h4>

Here's the session output:

```ruby
# Create and display two hashes.
h0 = {:a => 0, :b => 1}
p h0
{:a=>0, :b=>1}
h1 = {:b => 2, :c => 3}
p h1
{:b=>2, :c=>3}

# Merge the second hash into the first.
h0.merge!(h1)
p h0
{:a=>0, :b=>2, :c=>3}

# Add an element.
h0.store(:d, 4)
p h0
{:a=>0, :b=>2, :c=>3, :d=>4}

# Remove an element.
h0.delete(:b)
p h0
{:a=>0, :c=>3, :d=>4}

```

<h4>Another Treatment</h4>

The "sections" in the code above are small, so showing the entire output at once  makes sense.  For larger passages, it can make sense to interleave code and remarks.

I'll re-do the above:

Create and display two hashes:

```ruby
h0 = {:a => 0, :b => 1}
p h0
{:a=>0, :b=>1}
h1 = {:b => 2, :c => 3}
p h1
{:b=>2, :c=>3}
```

Merge the second hash into the first:
```ruby
h0.merge!(h1)
p h0
{:a=>0, :b=>2, :c=>3}
```

Add an element:

```ruby
h0.store(:d, 4)
p h0
{:a=>0, :b=>2, :c=>3, :d=>4}
```

Remove an element:

```ruby
h0.delete(:b)
p h0
{:a=>0, :c=>3, :d=>4}

```

<h4>The Bash Command</h4>

Here's the <code>bash</code> command that does the work:

```bash
cat session_input.rb | irb > session_output.irb
```

The breakdown:
- The <code>cat</code> command puts the Ruby file <code>session_input.rb</code> onto <code>stdout</code>.
- It's then piped as input to <code>irb</code>.
- The <code>stdout</code> stream from <code>irb</code> is redirected to file <code>session_output.irb</code>.

<h4>Refinements</h4>

- By default, the session output will echo each line of the Ruby input, which in this case is mostly just noise.  I use option <code>--noecho</code> to suppress echoing.
- The session output begins with the line <code>Switch to inspect mode.</code>, which we don't need (or want).  I use the <code>tail</code> command to remove it:

The complete command:

```bash
cat session_input.rb | irb --noecho | tail +2 > session_output.irb
```

<h4>The Windows cmd Command</h4>

```cmd
type session_input.rb | irb --noecho > session_output.irb
```

There's no builtin <code>tail</code> utility (that I know of).