The Commandable mixin is a very quick and and easy way to make almost any class usable via a command line interface. It simply uses writer methods as option setters, and the first command line argument as the method to call, with the subsequent arguments passed to the method.
The only limitation of this approach (besides the weak control of the process) is that required options must be specified with the key=value notation.
class X include Clio::Commandable attr_accessor :quiet def bread(*args) ["BREAD", quiet, *args] end def butter(*args) ["BUTTER", quiet, *args] end end x = X.new x.execute_command("butter yum") => ["BUTTER", nil, "yum"] x.execute_command("bread --quiet") => ["BUTTER", true]
Commandable also defines command_missing and option_missing, which you can override to provide suitable results.
TODO: Maybe command_missing is redundant, and method_missing would suffice?
# File lib/clio/commandable.rb, line 86 def parse(obj, argv) case argv when String require 'shellwords' argv = Shellwords.shellwords(argv) else argv = argv.dup end argv = argv.dup args, opts, i = [], {}, 0 while argv.size > 0 case opt = argv.shift when /=/ parse_equal(obj, opt, argv) when /^--/ parse_option(obj, opt, argv) when /^-/ parse_flags(obj, opt, argv) else args << opt end end return args end
# File lib/clio/commandable.rb, line 113 def parse_equal(obj, opt, argv) if md = /^[-]*(.*?)=(.*?)$/.match(opt) x, v = md[1], md[2] else raise ArgumentError, "#{x}" end if obj.respond_to?("#{x}=") # TODO: to_b if 'true' or 'false' ? obj.send("#{x}=",v) else obj.option_missing(x, v) # argv? end end
# File lib/clio/commandable.rb, line 138 def parse_flags(obj, opt, args) x = opt[1..-1] c = 0 x.split(//).each do |k| if obj.respond_to?("#{k}=") obj.send("#{k}=",true) else obj.option_missing(x, argv) end end end
This is the fallback subcommand. Override this to provide a fallback when no command is given on the commandline.
# File lib/clio/commandable.rb, line 54 def command_missing raise NoCommandError end
Used to invoke the command.
# File lib/clio/commandable.rb, line 48 def execute_command(argv=ARGV) Commandable.run(self, argv) end
Override option_missing if needed. This receives the name of the option and the remaining arguments list. It must consume any argument it uses from the (begining of) the list.
# File lib/clio/commandable.rb, line 63 def option_missing(opt, *argv) raise NoOptionError, opt end
Generated with the Darkfish Rdoc Generator 2.