README.md in irb_hacks-0.2.3 vs README.md in irb_hacks-0.2.4

- old
+ new

@@ -1,172 +1,203 @@ -Yet Another Set of IRB Hacks +Yet another set of IRB hacks ============================ Setup ----- - $ gem sources --add http://rubygems.org - $ gem install irb_hacks +~~~ +$ gem sources --add http://rubygems.org +$ gem install irb_hacks +~~~ Add to your `~/.irbrc`: - require "rubygems" - require "irb_hacks" +~~~ +require "rubygems" +require "irb_hacks" +~~~ Now fire up IRB for a quick test: - $ irb - irb> ae - (snippet)>> +~~~ +$ irb +irb> ae +(snippet)>> +~~~ -If you see "(snippet)", you're ready to go. +If you see `(snippet)`, you're ready to go. -The Hacks +The hacks --------- -### Code Snippets -- `a` and `ae` ### +### 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! +~~~ +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"] +~~~ +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 +~~~ +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"} - ... +~~~ +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! +~~~ +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" +~~~ +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` ### +### 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](http://github.com/whymirror/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! +~~~ +$ 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 +~~~ +$ 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 +~~~ +$ 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 ### +### 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 = OpenHash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)] - ... +~~~ +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 = OpenHash[*fc_row.map {|k, v| [(k.to_sym rescue k), (v.to_s.strip rescue v)]}.flatten(1)] - IrbHacks.break(row) +~~~ +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> +~~~ +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" +~~~ +require "rubygems" +require "irb_hacks" - IrbHacks.conf.snippet_prompt = ">>> " +IrbHacks.conf.snippet_prompt = ">>> " +~~~ - -### Configuration Variables (`IrbHacks.conf.*`)### +### 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.