
A 20 minute Rails demo that I used as part of a “What is Ruby on Rails?” talk. The store was not designed or developed from scratch in 20 minutes but serves as a Cooking Show style demo of what is possible in a very short amount of time.
Quickie Mart on Github
Sam Stephenson has a pretty looking bash prompt screenshotted in his rbenv project’s README. All you have to do is:
- Set your Terminal theme to Basic. Make sure to re-set any preferences you might have (like no audible bell etc).
- Set your Terminal font to 13pt Inconsolata. This isn’t the exact font he uses but it’s as close as I could find.
- Set your ANSI Color for Normal White(7) to Tin (Crayons tab in color picker)
- Put this bash code from this gist at the end of your .profile file.
- Install rbenv so you don’t get the errors I got below because I’m still on RVM. :)

I covet, I steal.
Even though I don’t show it there, the bash script will do the git repo status magic for you on OSX. You need to brew install git and have the shell completion scripts in /usr/local (homebrew will do this).

Don Cheadle is the best version of Captain Planet there is. I hope you’ve already seen the video. If not, go now. I’ll wait.
As it typically happens, I was creating some nested data structure and was reminded of all the different combinations that there are. For example:
- An array of arrays.
[ [1,2,3], [4,5,6] ]
- A hash of arrays.
{ :lucky => [77,42], :unlucky => [666,13] }
- An array of hashes.
[ {:cat=>"meow"}, {:dog=>"ruff"} ]
- A hash of hashes.
{ :best_in_life => {:enemies => "crushed"}, :worst => { :meatloaf => "old"} }
And I realized that I hadn’t really played with a hash of hashes much. And now I realize why. It’s really pretty useless. It’s hard to work with and the additional key really isn’t all that useful. I found it much better to just denormalize the key into the data attributes. Anyway, you can see what I mean by reading and running what’s below.
We’re going to create Captain Planet and the planeteers in a 2D hash of hashes and do some searching, iterating and other simple things. This should illustrate also how an array of hashes is a bit better. You’ll see halfway through the program we redefine the planeteers.
# search a 2d hash
def spacer(msg)
puts "\n"
puts "-" * 50
puts msg
puts "-" * 50
end
# this is not really a good data structure but we'll use it anyway.
planeteers = {
:kwame => { :element => "earth", :from => "Ghana, Africa", :actor => "LeVar Burton" },
:wheeler => { :element => "fire", :from => "Brooklyn, NY", :actor => "Joey Dedio" },
:linka => { :element => "wind", :from => "Soviet Union", :actor => "Kath Soucie" },
:gi => { :element => "water", :from => "Thailand", :actor => "Janice Kawaye" },
:ma_ti => { :element => "heart", :from => "Brazil", :actor => "Scott Menville" }
}
spacer "Here are our planeteers and their elements:"
puts planeteers.keys.collect {|p| {p => planeteers[p][:element]} }
puts "\nFind the fire planeteer:\n"
fire = planeteers.keys.collect {|p| {p => planeteers[p][:element]=="fire"} }
# => [{:kwame=>false}, {:wheeler=>true}, {:linka=>false}, {:gi=>false}, {:ma_ti=>false}]
only_fire = fire.select{|h| h.values[0] == true}
# => {:wheeler=>true}
# print just one
puts only_fire.first.keys.first
spacer "Let's do this a bit cleaner with a better data structure."
planeteers = [
{ :name => "kwame", :element => "earth", :from => "Ghana, Africa", :actor => "LeVar Burton" },
{ :name => "wheeler", :element => "fire", :from => "Brooklyn, NY", :actor => "Joey Dedio" },
{ :name => "linka", :element => "wind", :from => "Soviet Union", :actor => "Kath Soucie" },
{ :name => "gi", :element => "water", :from => "Thailand", :actor => "Janice Kawaye" },
{ :name => "ma_ti", :element => "heart", :from => "Brazil", :actor => "Scott Menville" }
]
planeteers.max_by {|p| p[:name]}
# => {:name=>"ma_ti", :element=>"heart", :from=>"Brazil", :actor=>"Scott Menville"}
planeteers.max_by {|p| p[:element]}
# => {:name=>"linka", :element=>"wind", :from=>"Soviet Union", :actor=>"Kath Soucie"}
puts "Find the heart planeteer:"
puts planeteers.select {|p| p[:element] == "heart" }.first[:name]
# first we'll put a fake planeteer on the end for cpt planet
planeteers << { :name => "all", :element => "go planet" }
spacer "Let's summon Captain Planet!"
planeteers.each do |planeteer|
puts "#{planeteer[:name].capitalize}: #{planeteer[:element].capitalize}!"
end
# pop off fake guy
planeteers.pop
Here’s what it spits out:
--------------------------------------------------
Here are our planeteers and their elements:
--------------------------------------------------
{:kwame=>"earth"}
{:wheeler=>"fire"}
{:linka=>"wind"}
{:gi=>"water"}
{:ma_ti=>"heart"}
Find the fire planeteer:
wheeler
--------------------------------------------------
Let's do this a bit cleaner with a better data structure.
--------------------------------------------------
Find the heart planeteer:
ma_ti
--------------------------------------------------
Let's summon Captain Planet!
--------------------------------------------------
Kwame: Earth!
Wheeler: Fire!
Linka: Wind!
Gi: Water!
Ma_ti: Heart!
All: Go planet!

Since the hbase shell is irb, I wanted to get color output because that’s what I’m used to. Although the appropriate place to put this is in an .irbrc file, that would conflict with any ruby development environment already on the system and luckily jruby and hbase don’t seem to invoke it anyway.
First find a copy of wirble. If you don’t have it anywhere, download it from github:
cd ${hbase_home}/lib/ruby
wget https://raw.github.com/blackwinter/wirble/master/lib/wirble.rb
Now edit ${hbase_home}/bin/hirb.rb. Add to the end but above IRB.start
begin
# load wirble
require 'wirble'
# start wirble (with color)
Wirble.init
Wirble.colorize
rescue LoadError => err
warn "Couldn't load Wirble: #{err}"
end
IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.hbase-history"
# add right before end but above this line
IRB.start
Now when you start hbase shell, you’ll have lovely color output. Why would you want this? I don’t know. You probably don’t want it. But I was happy to understand how the hbase shell works. It’s just jruby irb that loads hirb automatically.