Skip to content

Instantly share code, notes, and snippets.

@vizvamitra
Created June 1, 2014 02:01
Show Gist options
  • Save vizvamitra/b33d473b58390e121da8 to your computer and use it in GitHub Desktop.
Save vizvamitra/b33d473b58390e121da8 to your computer and use it in GitHub Desktop.
module Commandor
private
class Command
def self.match?(arg); end
def self.parse(argv) end
def self.execute(*args); end
def self.help_msg; ''; end
end
module ClassMethods
def process argv, *args
argv << '-h' if argv.empty?
command = argv.shift
self.each do |cmd|
if cmd.match? command
opts = cmd.parse(argv)
cmd.execute opts, *args
break
end
end
end
def help_msg
self.inject("") {|out, cmd| out << cmd.help_msg << "\n"}
end
### Command creation methods
private
def command name
command_name = name.capitalize+'Command'
@new_class = self.const_set(command_name, Class.new(Command))
yield
@commands << @new_class
@new_class = nil
end
def match *args
block = block_given? ? lambda{|arg| yield(arg)} : lambda{|arg| args.include? arg}
@new_class.instance_variable_set(:@match_list, args)
@new_class.define_singleton_method(:match?) do |arg|
block.call(arg)
end
end
def parse &block
@new_class.define_singleton_method(:parse) do |argv|
block.call(argv)
end
end
def execute &block
@new_class.define_singleton_method(:execute) do |*args|
block.call(*args)
end
end
def help arg_names, help_txt
@new_class.define_singleton_method(:help_msg) do
" #{@match_list.join(', ')} #{arg_names}#{help_txt}"
end
end
end
def self.included(klass)
klass.extend(ClassMethods)
klass.instance_variable_set(:@commands, [])
klass.extend Enumerable
def klass.each
@commands.each do |cmd|
yield cmd
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment