Benny is happy to announce his next gem: 
  "lazyscript"
 
Dear list, 
 
I hope this is useful for someone and I am curious what you think about it. 
 
== Overview
LazyScript offers an easy way to create text based applications that are
dealing with several interdependant parts and that may require input from 
a user (bascially selection of options and input).

This parts are called "Modes". Each mode has got a corresponding dialog with
its methods called "Screen".

The name of the screen is the lowercase name of the mode.

All you have to do is to create subclasses of "Mode" and define the methods
of the modes which will show up in the Screens.

And then you may define titles for the screens and additional entries to
jump from one mode-screen to another.

If you have the rubygem ncurses installed you even get ncurses based dialogs
for free.
 
== Example of Usage

require 'rubygems'
require_gem 'lazyscript'
include LazyScript

# loads the config file, it will be created for you, if it doesn't exist
load_config("myscript.yaml")

# defines a mode with the name 'database'
class Database < Mode
  # the path shown in the status bar (where we are in the dialogs).
  # the name of a currently chosen database appended to this path
  def path
    "database/"
  end

  # defines a hash of keys shown to select a certain database. 
  # the values are the result you get
  def select
    {"database1" => "a", "database2" => "b", "database3" => "c"}
  end

  # defines which methods should not be shown in the screen "database"
  def hidden_methods()
    ["add", "delete"]
  end
end

# defines a mode with the name 'schema'
class Schema < Mode
  # from(Database) forces a database to be selected before 
  # we could deal with a schema. this results in a dialog popping up 
  # to select a database from the list above (see Database#select)
  # and return to the schema screen after a database was chosen
  # then the name of the chosen database is shown in the path followed 
  # by a dot and the name of the currently chosen schema
  # (if there is one chosen). since we use lazy evaluation 
  # (see lazyvalue.rb) the database selection is one asked once 
  # and then cached
  def path
    "#{from(Database)}."
  end

  # a method that requires some other input
  def special_question
    # see the gem "highline" for more infos of the syntax 
    # of "say" and "ask" (it even works with ncurses)
    say("I want to ask you some questions:")
    age = ask("How old are you?")
    gender = ask("Are you male / female?", [:male, :female])
  end
end

# defines a mode with the name 'table'
class Table < Mode
  # here first the selection of a database is forced and after that 
  # the selection of a schema (see Schema#path)
  def path
    "#{from(Database)}.#{from(Schema)}."
  end

  # here we use from(Database) and from(Schema) again to get the 
  # selected ones or force a selection if they haven't been selected before
  # if you want to know more about how you may define from(SomeThing) or
  # to(SomeThing) yourself look at the gem "FaceToFace"
  def select
    db = from(Database)
    schema = from(Schema)
    hsh= {"table1" => "", "table2" => "", "table3" => ""}
  end

  # here an example how to use the add method to add a table
  def add()
    # force to rechoose database and scheme, even if they already have 
    # been chosen
    HANDLER.reset("database")
    HANDLER.reset("schema")

    # get the new choices
    db = from(Database)
    schema = from(Schema)

    # here Mode#add is called. in the block you place your normal code.
    # if block return true, the action is concidered to be successful, 
    # if it returns false as unsuccessful
    super() do |name|
      # name is the name for the new table entered by the user
      #say "added #{db}.#{schema}.#{name}"
      true
    end
  end

  # here an example how to use the delete method to delete a table
  def delete()
    # force the selection of the table that should be deleted
    table = from(Table)

    # call Mode#delete to ask if the table should be deleted. 
    # if the response is "yes" then the block will
    # be executed, otherwise the table screen will be shown
    # if the block returns true, the deletion will be considered 
    # as successful, if false then as unsuccessful
    super(table) do
      # delete it
      true
    end
  end
end


== Example of configuration file
  - 'main' is the first screen shown when you start the application
  - 'children' specifies other screens that may be reached from this screen
  - 'title' is the title of the screen shown at the top of the screen
  NOTE that YAML style requires indentation of 2 spaces - no tabs!

--- 
SCREENS:
  main:
    title: "\n\n#-- Welcome to our little Example --#\n"
      children:
        - database
        - framework
        - project
      database:
        title: Database
        children:
          - schema
          - table
      schema:
        title: Schema
        children:
          - table

== Future
 - the ncurses dialogs will have to be further refined
 - add some cmdparse hacks to allow direct usage of the modes without
dialogs
 - maybe even implement the dialogs in a GUI lib (with fallback to textmode)
and as webrick dialogs. this would enable us to write applications that may
run with any interface without having to care about the interface

== Where may I find a complete example?
have a look at tests/example.rb

Project Website: http://rubyforge.org/projects/lazyscript/ 
Contact: linux / marcrenearns.de