2

I am writing an command line application which uses the keyboard to show the user the currently selected option as well as selecting an option, and other functions like displaying all possible commands.

My question is, what are the best practices in ruby to accomplish this? I currently have an input_handler class which gets initialized with the class I want to perform the action. The input handler uses a command class which actually runs the methods attached to the command. The code I have looks like below:

class Command
  attr_reader :key, :alt_name, :action_object, :action, :registered

  def initialize(key, alt_name=nil)
    @key = key.to_s
    @alt_name = alt_name == nil ? @key.to_sym : alt_name.to_sym
    @registered = false
  end

  def send(input)
    @action_object.send(action, input)
  end

  def register(action_object, action)
    @action_object = action_object
    @action = action
    @registered = true
  end

  def is_command?(key)
    @key == key.to_s || @alt_name == key.to_s.to_sym
  end
end

class InputHandler
  include InputHelper
  attr_reader :commands

  def initialize(action_object)
    @action_object = action_object
    generate_commands
  end

  #Returns whatever the command action returns
  def get_input
    input = read_char
    get_command(input).send(input) if get_command(input).registered
  end

  def register_commands(command_hash)
    command_hash.keys.each do |key|
        get_command(key).register(@action_object, command_hash[key])
    end
  end

  def registered
    @commands.select {|command| command.registered == true}
  end
end

I am wondering if I am following the proper way to map methods to key presses (the read_char method reads the first key input without requiring enter to be pressed). Is the way I have it written prone to difficult debugging, or is the way I have it written too indirect making it easy to introduce bugs?

2
  • "am following the proper way…" Does it work? Commented Jul 19, 2015 at 18:30
  • Before I write a very long answer on how to do this, are you using linux, mac, or Windows? Commented Jul 19, 2015 at 18:34

1 Answer 1

1

Ruby ships with readlines, may you could use it to do the dirty work:

require 'readline'

LIST = [
  'search', 'download', 'open',
  'help', 'history', 'quit',
  'url', 'next', 'clear',
  'prev', 'past'
].sort

comp = proc { |s| LIST.grep(/^#{Regexp.escape(s)}/) }

Readline.completion_append_character = " "
Readline.completion_proc = comp

while line = Readline.readline('> ', true)
  p line
end

(from the docs) It uses tab for auto-completion and tabtab for listing, so "s{tab}" results in "search", "p{tab}{tab}" in "past prev".

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.