The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Mini Irb and Mini Script/Console

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Gabriel Horner

Posts: 62
Nickname: cldwaker
Registered: Feb, 2009

Gabriel Horner is an independent consultant who can't get enough of Ruby
Mini Irb and Mini Script/Console Posted: Jul 23, 2009 5:25 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Gabriel Horner.
Original Post: Mini Irb and Mini Script/Console
Feed Title: Tagaholic
Feed URL: http://feeds2.feedburner.com/tagaholic
Feed Description: My ruby/rails/knowledge management thoughts
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Gabriel Horner
Latest Posts From Tagaholic

Advertisement

In my last post, I introduced Bond‘s own version of irb’s completion. What I didn’t emphasize is that it doesn’t need irb. To prove it, I’ll show you a mini irb which has persistent readline history, error handling and Bond’s autocompletion … in 7 lines.

Mini Irb

A good starting point for a basic irb comes from this github snippet:

  loop do
   print '>> '
   output = eval($stdin.gets)
   print '=> '
   puts output.inspect
  end

It’s got the very basics of a repl: take a user’s input, eval it and print the result. Being as basic as it is, there’s no autocompletion, persistent readline history, etc.

But who says that needs to be much larger to get those features?:

1   %w{readline rubygems bond bond/completion}.each {|e| require e }
2   history_file = File.join(ENV["HOME"], '.mini_irb_history')
3   IO.readlines(history_file).each {|e| Readline::HISTORY << e.chomp } if File.exists?(history_file)
4   while (input = Readline.readline('>> ', true)) != 'exit'
5     begin puts "=> #{eval(input).inspect}"; rescue Exception; puts "Error: #{$!}" end
6   end
7   File.open(history_file, 'w') {|f| f.write Readline::HISTORY.to_a.join("\n") }

A line by line play:

  • Line 1: Loads readline, bond and bond’s improved version of irb-like completion.
  • Line 2-3: Read in previous history from a history file.
  • Line 4: Get the users input and start a loop that only ends with exit.
  • Line 5: Evaluate the input and print an exception if it occurs.
  • Line 7: Write all of the loaded history back to the history file.

If you’re not familiar with readline, you may be wondering where is the autocompletion being handled? Well, all of readline’s goodness is channeled through Readline.readline. Bond simply sets Readline.completion_proc and readline handles the rest. If you’d like to play with this, fork away!

Here’s what mini-irb looks like:

  bash > ruby mini-irb.rb
  # Unlike irb, mini-irb correctly completes on chains of objects
  >> :some.to_s.split('').a
  ).all?   ).any?   ).assoc  ).at

  # Completes require's arguments
  >> require 'a[TAB]
  >> require 'abbrev.rb'
  => true

  # Completes files
  >> File.read '~/[TAB]
  >> File.read '/Users/bozo/.ir[TAB]
  >> File.read '/Users/bozo/.irbrc'

  # Oh noz, wherz my irbz?
  >> IRB
  Error: (eval):1: uninitialized constant IRB

  # Try this one in irb
  >> raise Exception
  Error: Exception

  >> exit
  bash>

Mini script/console

Just for fun I figured I’d see how much more code it’d take to make a mini script/console for Rails. I’m sorry. It took one more line:

  ['readline', 'rubygems', 'bond','bond/completion', File.dirname(__FILE__) + '/../config/boot'].each {|e| require e }
  ["#{RAILS_ROOT}/config/environment", 'console_app', 'console_with_helpers'].each {|e| require  e}
  history_file = File.join(ENV["HOME"], '.myrb_history')
  IO.readlines(history_file).each {|e| Readline::HISTORY << e.chomp } if File.exists?(history_file)
  while (input = Readline.readline('>> ', true)) != 'exit'
    begin puts "=> #{eval(input).inspect}"; rescue Exception; puts "Error: #{$!}" end
  end
  File.open(history_file, 'w') {|f| f.write Readline::HISTORY.to_a.join("\n") }

To be fair this is a stripped down version of script/console i.e. it doesn’t offer the debugger or sandbox. But those could be easily added. If you want to improve on this, fork away! If you want to see what this looks like, just give it a try. :)

Comparing Apples to Oranges

So how does mini-irb compare to irb? Well, it’s like comparing apples to oranges. Irb weighs in at 5000+ loc while mini-irb is 7 + 540 loc with Bond. Irb sports a number of features which I’ve documented extensively. But I’m finding less need for them every day. The only feature I’d keep is the ruby lexer to handle multiple lines of code. But even then I’d rather prototype multiple lines in an editor.

What are your two cents? What features from irb would you add to mini-irb?

Read: Mini Irb and Mini Script/Console

Topic: How to get a (local) user's home directory on Windows Previous Topic   Next Topic Topic: Better Irb Completion With Bond

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use