title: Best way to map keyboard input to methods in ruby
body: <p>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.</p>
  
  <p><strong>My question is, what are the best practices in ruby to accomplish this?</strong> 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:</p>
  
  <pre><code>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
  </code></pre>
  
  <p>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?</p>