Skip to content

Commit

Permalink
README
Browse files Browse the repository at this point in the history
  • Loading branch information
rossmeissl committed Mar 8, 2011
1 parent d1fbccf commit a616859
Show file tree
Hide file tree
Showing 3 changed files with 172 additions and 25 deletions.
171 changes: 171 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
= bombshell

Ever wanted to give dudes the ability to explore your library interactively? Like, with a custom IRB-like shell/console?

Really, you did? Weird.

== Simple example

`pizza/bin/pizza`:

{% highlight ruby %}
#!/usr/bin/env ruby
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')

require 'rubygems'
require 'pizza'
Bombshell.launch(Pizza::Shell)
{% endhighlight %}

`pizza/lib/pizza/shell.rb`:
{% highlight ruby %}
require 'bombshell'

module Pizza
class Shell < Bombshell::Environment
include Bombshell::Shell

prompt_with 'pizzabot'

def order(size)
Pizza::Order.new(:size => size).place!
puts 'Your pizza has been ordered! Super!'
end
end
end
{% endhighlight %}

Let's try it out:
> $ pizza
> pizzabot> order 'large'
> Your pizza has been ordered! Super!
> pizzabot>
== Prompts

You set your prompt like this:

{% highlight ruby %}
prompt_with 'pizza_bot_loves_you'
{% endhighlight %}

Or like this:

{% highlight ruby %}
prompt_with do
"pizza_bot / #{Time.now}" # binding is on your shell *class*
end
{% endhighlight %}

Or even like this:

{% highlight ruby %}
prompt_with do |shell|
"pizza_bot / #{shell.size}" # the block gets the shell *instance* when it asks for it
end
{% endhighlight %}

== Callbacks

You can set callbacks like this:

{% highlight ruby %}
before_launch do
init # binding is on your shell *class*
end

before_launch do |size|
Pizza.default_size = size # the block gets as many command-line parameters as you ask for
end

having_launched do
puts size if size # binding is on your shell *instance*
end
{% endhighlight %}

== Subshells

If you dump all of your functionality into one shell, things could get a little messy. That's why we have *subshells*:

`pizza/lib/pizza/shell.rb`:
{% highlight ruby %}
require 'bombshell'

module Pizza
class Shell < Bombshell::Environment
include Bombshell::Shell
prompt_with 'pizzabot'

def pizza
Order.launch
end
end
end
{% endhighlight %}

`pizza/lib/pizza/shell/order.rb`:
{% highlight ruby %}
require 'bombshell'

module Pizza
class Shell
class Order < Bombshell::Environment
include Bombshell::Shell
prompt_with 'new order'

def size(s)
@size = s
puts 'You got it!'
end

def topping(t)
@toppings ||= []
@toppings << t
puts "Added #{t}"
end

def order
Pizza::Order.new :size => @size, :toppings => @toppings
puts 'Coming right up!'
quit
end
end
end
end
{% endhighlight %}

And now we have . . .

Let's try it out:

> pizzabot> pizza
> new order> size 'large'
> You got it!
> new order> topping 'pepperoni'
> Added pepperoni
> new order> order
> Coming right up!
> pizzabot>
== Tab completion

It's there. Give it a whirl with TAB.

== To use:

* Create a class for your shell and `include Bombshell::Shell`. You should also set this class to inherit from `Bombshell::Environment` as that will ensure your shell doesn't have any extraneous "commands" (i.e. methods) inherited from Object. (If you'd rather use a different basis---like `CleanSlate`---or `undef` methods yourself, go right ahead.)

* Define your commands as instance methods on this class. There's nothing *too* funny going on here, it's just Ruby.

* Kick off the shell with Bombshell.launch(YourShellClass). It's possible to do this from IRB but it's kind of messy (constant reassignment warnings). Instead, set up a "binary" for yourself like `pizza/bin/pizza` at the top of this file.

== Hints:

* Give your users a `help` command!
* Use subshells for hierarchical interactivity!
* Provide as thin of a wrapper you can above your library! We want to see what's going on!

== Copyright

Copyright (c) 2011 Andy Rossmeissl. See LICENSE.txt for
further details.
19 changes: 0 additions & 19 deletions README.rdoc

This file was deleted.

7 changes: 1 addition & 6 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,13 @@ require 'rake'

require 'jeweler'
Jeweler::Tasks.new do |gem|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
gem.name = "bombshell"
gem.homepage = "http://github.com/rossmeissl/bombshell"
gem.license = "MIT"
gem.summary = %Q{Custom IRB consoles made easy}
gem.description = %Q{Custom IRB consoles made easy}
gem.description = %Q{Give your application or gem an interactive shell, complete with custom prompts, tab completion, and various callbacks. Commands are defined as Ruby methods and can be grouped into logical subshells.}
gem.email = "[email protected]"
gem.authors = ["Andy Rossmeissl"]
# Include your dependencies below. Runtime dependencies are required when using your gem,
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
# gem.add_development_dependency 'rspec', '> 1.2.3'
end
Jeweler::RubygemsDotOrgTasks.new

Expand Down

0 comments on commit a616859

Please sign in to comment.