Hello. Please CC me any replies to this message; I was using
comp.lang.ruby, but I don't appear to have news access at my current
account.

I've recently begun learning Ruby. I'd really like to use it to code a
few console apps which I'm planning on developing. I'm a Python coder,
and one class which I missed tremendously during the Ruby migration
was cmd, which quickly constructs command line interpreters.

So, in order to better learn Ruby, I decided to port the cmd
class. Yes I know about the Ruby python interpreter, but I'd rather
avoid that if I can. So, several hours and a few pots of coffee later,
I've got most of the cmd class ported. I still have to add the help
facilities, and I may get brave and try to support readline, but first
things first. :)

Anyhow, I've poured over this code for a few hours. There's an error
in the onecmd method, but I can't find it. It's probably something
rediculously silly, but after coding for hours I'm just not seeing
it. I'll attach the code and blatantly-ripped-off spec which it was
ported from; would someone be able to help me track down what's going
on? I'll include a transcript of 'ruby cmd.rb' below as well.

--------------------------------------------------------------------------------
# A generic class to build line-oriented command interpreters
#
# Interpreters constructed with this class obey the following conventions:
#
# 1. End of file on input is processed as the command 'EOF'.
# 2. A command is parsed out of each line by collecting the prefix composed
#    of characters in the identchars member.
# 3. A command `foo' is dispatched to a method 'do_foo()'; the do_ method
#    is passed a single argument consisting of the remainder of the line.
# 4. Typing an empty line repeats the last command.  (Actually, it calls the
#    method `emptyline', which may be overridden in a subclass.)
# 5. There is a predefined `help' method.  Given an argument `topic', it
#    calls the command `help_topic'.  With no arguments, it lists all topics
#    with defined help_ functions, broken into up to three topics; documented
#    commands, miscellaneous help topics, and undocumented commands.
# 6. The command '?' is a synonym for `help'.  The command '!' is a synonym
#    for `shell', if a do_shell method exists.
#
# The `default' method may be overridden to intercept commands for which there
# is no do_ method.
#
# The data member `self.ruler' sets the character used to draw separator lines
# in the help messages.  If empty, no ruler line is drawn.  It defaults to "=".
#
# If the value of `self.intro' is nonempty when the cmdloop method is called,
# it is printed out on interpreter startup.  This value may be overridden
# via an optional argument to the cmdloop() method.
#
# The data members `@doc_header', `@misc_header', and
# `@undoc_header' set the headers used for the help function's
# listings of documented functions, miscellaneous topics, and undocumented
# functions respectively.
#

class Cmd
  @prompt = ">"
  @identchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMOPQRSTUVWXYZ123456789_"
  @ruler = "="
  @lastcmd = ""
  @cmdqueue = []
  @intro = nil
  @doc_leader = ""
  @doc_header = "Documented commands (type help <topic>):"
  @misc_header = "Miscellaneous help topics:"
  @undoc_header = "Undocumented commands:"
  @nohelp = "*** No help on %s"
  
  def preloop
  end # preloop

  def postloop
  end # postloop

  def precmd line
    line
  end # precmd

  def postcmd line
    line
  end # postcmd

  def emptyline
    return self.onecmd @lastcmd if @lastcmd
  end # emptyline

  def default line
    print "*** Unknown syntax:"+line+"\n"
  end # default

  def onecmd line
    line = line.strip
    line = "help" if line == "?"
    line = "shell" if line == "!" and self.method_defined?("do_shell")
    return self.emptyline if line == ""
    @lastcmd = line
    i, n = 0, line.length
    while i < n
	break if not (line[i] === @identchars)
	i++
	end # while i < n
    cmd = line[0,i]
    arg = line[i, line.length].strip
    return self.default line if cmd == ""
    return self.module_eval("self.do_"+cmd+"("+arg+")") if self.method_defined?("do_"+cmd)
    self.default(line)
  end # onecmd
  
  def cmdloop(intro=nil)
    self.preloop
@intro = intro if intro
    print @intro+"\n\n" if @intro
    stop = nil
    while not stop
      if @cmdqueue.length > 0
	line = @cmdqueue[0]
	@cmdqueue.delete_at 0
      else
	print @prompt
	line = gets
      end # if @cmdqueue.length > 0
      line = self.precmd line
      stop = self.onecmd line
      stop = self.postcmd stop line
    end # while not stop
    self.postloop
  end # cmdloop
end # class Cmd
--------------------------------------------------------------------------------

cmd.rb:80: parse error
	end # while i < n
	   ^
cmd.rb:88: nested method definition
  def cmdloop(intro=nil)
              ^
cmd.rb:107: parse error
Exit 3


Thanks in advance for any assistance!