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 irb
, the Interactive Ruby Shell, to build examples. In irb
, 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.
Ruby Session Input
This code is in a file that will be fed to irb
as input. As the code executes, it uses method Kernel#p
to display and re-display values, showing how they have changed:
# 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
Session Output
Here's the session output:
# 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}
Another Treatment
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:
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}
The Bash Command
Here's the bash
command that does the work:
cat session_input.rb | irb > session_output.irb
The breakdown:
- The
cat
command puts the Ruby filesession_input.rb
ontostdout
. - It's then piped as input to
irb
. - The
stdout
stream fromirb
is redirected to filesession_output.irb
.
Refinements
- By default, the session output will echo each line of the Ruby input, which in this case is mostly just noise. I use option
--noecho
to suppress echoing. - The session output begins with the line
Switch to inspect mode.
, which we don't need (or want). I use thetail
command to remove it:
The complete command:
cat session_input.rb | irb --noecho | tail +2 > session_output.irb
The Windows cmd Command
type session_input.rb | irb --noecho > session_output.irb
There's no builtin tail
utility (that I know of).