Skip to content

dadooda/irb_hacks

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yet another set of IRB hacks

IMPORTANT INFORMATION for Rails 4.0.x users

2014-02-17: I've noticed that under Rails 4.0.2 and Ruby 2.1.0 irb_hacks is badly affecting the development backtrace reporter. I.e., "We're sorry ..." is displayed even in development environment with no details in logs, too.

This is causing major inconvenience and I'm looking for opportunities to fix this issue when time permits. Until then, please stay warned.

Setup

$ gem sources --add http://rubygems.org
$ gem install irb_hacks

Add to your ~/.irbrc:

require "rubygems"
require "irb_hacks"

Now fire up IRB for a quick test:

$ irb
irb> ae
(snippet)>>

If you see (snippet), you're ready to go.

The hacks

Code snippets -- a and ae

There's often a need to invoke our work-in-progress code a number of times using the same arguments, wrapping block, etc. For that, "code snippets" feature is quite handy.

irb_hacks provides the two methods with short, meaningless (and thus conflict-free) names -- a and ae. a means nothing, it's just the first letter of the alphabet. a invokes the last-edited snippet. ae lets you edit the actual snippet (it roughly stands for "a" + "edit").

A very basic example:

irb> ae
(snippet)>> puts "Hello, world!"
irb> a
Hello, world!

Snippet arguments are supported. It's an array called args in snippet context.

irb> ae
(snippet)>> p "args", args
irb> a 10, 1.0, "a string"
"args"
[10, 1.0, "a string"]

Snippets work just like normal Ruby methods -- they return the value of the last statement executed.

irb> ae
(snippet)>> ["alfa", "zulu", "bravo"] + args
irb> puts a("charlie").sort
alfa
bravo
charlie
zulu

Snippets support code blocks. It's a Proc object called block in snippet context. Usage example follows. Suppose you're building a simplistic /etc/passwd parser. You put the actual reading in the snippet, but do line data manipulation in a block:

irb> ae
(snippet)>> File.readlines("/etc/passwd").map(&block).each {|s| p s}; nil
irb> a {|s| ar = s.split(":"); {:name => ar[0], :uid => ar[2]}}
{:uid=>"0", :name=>"root"}
{:uid=>"1", :name=>"bin"}
{:uid=>"2", :name=>"daemon"}
{:uid=>"3", :name=>"adm"}
...

Snippets are persistent thoughout IRB invocations. That's quite handy, since not all stuff can be dynamically reloaded and sometimes we have to restart IRB to ensure a clean reload.

irb> ae
(snippet)>> puts "Snippets are persistent!"
irb> exit
$ irb
irb> a
Snippets are persistent!

Just in case, snippet history file is called ~/.irb_snippet_history by default.

Snippets maintain their own Readline history. When you press [Up] and [Down] keys in ae, you browse the previously used snippets, not just your previous IRB input. So don't retype the snippet you used yesterday -- press [Up] a few times and you'll see it.

irb> ae
(snippet)>> puts "snippet one"
irb> hala
irb> bala
irb> ae
(snippet)>> puts "snippet two"
irb> foo
irb> moo
irb> ae
(snippet)>>
# Pressing [Up] will give you...
(snippet)>> puts "snippet two"
# Pressing [Up] again will give you...
(snippet)>> puts "snippet one"

You can configure some aspects of the snippets. Read "Configuration" chapter below.

Browse program data with GNU less

Sometimes the data your code works with is too long to fit in a console window. The clearest example of this are variables filled with text content, e.g. Hpricot documents/elements.

To solve that, the greatest paging program of all times, GNU less, comes to the rescue.

$ irb
irb> files = Dir["/etc/*"].sort
# Some bulky array...
irb> less files
# ...which you browse interactively!

In block form, less hack intercepts everything output to STDOUT (and, optionally, to STDERR), and feeds it to the pager.

$ irb
irb> less do
puts "Hello, world"
end

Now with STDERR capture:

$ irb
irb> less(:stderr) do
puts "to stdout"
STDERR.puts "to stderr"
end

You can configure which pager program to use and with which options. Read "Configuration" chapter below.

Break execution and return instant value

By using IrbHacks.break(value) you break snippet (a) execution and make it return value. This is a simple yet powerful debugging technique.

Suppose you're debugging the code which contains something like:

csv.each_with_index do |fc_row, i|
  row = Hash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
  ...

There's something wrong with the code and you want to see if row is given the correct value. To do it, use IrbHacks.break:

csv.each_with_index do |fc_row, i|
  row = Hash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)]
  IrbHacks.break(row)

Now all you have to do is write an ae snippet and call it. row value will be available in IRB for inspection:

irb> ae
(snippet)>> Klass.new.method(args)
irb> row = a
# Back in IRB. Do whatever you want with `row` value now.
irb>

Each IrbHacks.break call raises an IrbHacks::BreakException. If you see them popping out runtime, find the appropriate IrbHacks.break calls and defuse them.

Configuration

Via IrbHacks.conf object you can configure various features of irb_hacks. Add IrbHacks.conf manipulation code to your .irbrc:

require "rubygems"
require "irb_hacks"

IrbHacks.conf.snippet_prompt = ">>> "

Configuration variables (IrbHacks.conf.*)###

  • less_cmd -- System command to invoke pager for less.
  • snippet_history_file -- Snippet (a, ae) history file.
  • snippet_history_size -- Snippet history size.
  • snippet_prompt -- Snippet input prompt.

Copyright

Copyright © 2010-2012 Alex Fortuna.

Licensed under the MIT License.

Feedback

Send bug reports, suggestions and criticisms through project's page on GitHub.

About

Yet Another Set of IRB Hacks

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages