Interpretador de comandos simples em ruby

Olá pessoal.

Estou estudando ruby a pouco tempo e no momento estou lendo o livro “O Programador Pragmático”.
Neste livro encontrei um exercício onde pede-se para construir um interpretador de comandos bem simples onde o importante é que seja fácil adicionar novos comandos nesta “minilinguagem”.
Criei o programa abaixo mas acho que ele pode ser escrito de forma bem melhor usando recursos mais elaborados que o ruby oferece.
Gostaria de ver outras idéias de programadores ruby com mais experiência e também de receber críticas sobre este código.

Caso este tópico for noob demais, peço desculpas galera.

Valeu.

class Interpreter

  def initialize
    @cmds = Commands.available_commands
  end

  def execute
    c = Commands.new
    while (true)
      input = gets()
      tmp = input.split(" ")
      cmd = tmp[0] # comando
      prm = tmp[1] # parametro

      if c.respond_to? @cmds[cmd][1] 
        c.send(@cmds[cmd][1], prm) if @cmds[cmd][0]
        c.send(@cmds[cmd][1]) unless @cmds[cmd][0]
      else
        puts "comando nao suportado"
      end

    end
  end

end

# comandos disponíveis - para mais comandos adicionar métodos 
class Commands 

  def self.available_commands
    { "P" => [true,  :doSelectPen], 
      "D" => [false, :doPenDown], 
      "U" => [false, :doPenUp] }
  end

  def doSelectPen(size)
    puts "selected pen #{size}"
  end

  def doPenDown
    puts "down pen"
  end

  def doPenUp
    puts "up pen"
  end
end

# inicia a execução do programa
i = Interpreter.new
i.execute

Interessante…
Acho que o programa poderia dar suporte a leitura dos comandos a partir de um arquivo, que seria o uso mais comum para uma minilinguagem.

Tentei jogar pela entrada padrão através de um pipe, até que funcionou mas no fim deu erro porque ele não sabia tratar o fim de arquivo.

>type interpreter.dat
P 10
U
D
U
P 50

>type interpreter.dat | jruby interpreter.rb
selected pen 10
up pen
down pen
up pen
selected pen 50
NoMethodError: private method `split' called for nil:NilClass
  execute at interpreter.rb:11
   (root) at interpreter.rb:51

Também seria um ótimo desafio tentar suportar comandos complexos (armazenamento de estado entre comandos, dependência entre eles, execução de blocos condicionais, etc). Talvez aí já entre um pouco de teoria de compiladores.

[quote=gomesrod]Interessante…
Acho que o programa poderia dar suporte a leitura dos comandos a partir de um arquivo, que seria o uso mais comum para uma minilinguagem.

Tentei jogar pela entrada padrão através de um pipe, até que funcionou mas no fim deu erro porque ele não sabia tratar o fim de arquivo.

>type interpreter.dat
P 10
U
D
U
P 50

>type interpreter.dat | jruby interpreter.rb
selected pen 10
up pen
down pen
up pen
selected pen 50
NoMethodError: private method `split' called for nil:NilClass
  execute at interpreter.rb:11
   (root) at interpreter.rb:51

Também seria um ótimo desafio tentar suportar comandos complexos (armazenamento de estado entre comandos, dependência entre eles, execução de blocos condicionais, etc). Talvez aí já entre um pouco de teoria de compiladores.[/quote]

Legal Gomesrod!
Poderia compartilhar seu código?

No exercício do livro a idéia era que fosse algo bem simples mesmo.
Uma coisa que fiz também foi escrever o código em java e em C para comparar as diferentes maneiras de resolver o problema.
Apesar de eu trabalhar atualmente com java, realmente em ruby o código ficou bem mais simples.

Valeu

Eu não fiz nada não, só dou pitaco no dos outros mesmo! rsrsrs

O que fiz ali foi gravar o seu programa no arquivo interpreter.rb , os comandos no interpreter.dat, e executar.