Class | Console::Command |
In: |
lib/facets/more/command.rb
|
Parent: | Object |
Console::Command provides a clean and easy way to create a command line interface for your program. The unique technique utlizes a Commandline to Object Mapping (COM) to make it quick and easy.
Let‘s make an executable called ‘mycmd’.
#!/usr/bin/env ruby require 'facets' require 'command' MyCmd << Console::Command def _v $VERBOSE = true end def jump if $VERBOSE puts "JUMP! JUMP! JUMP!" else puts "Jump" end end end MyCmd.execute
Then on the command line:
% mycmd jump Jump % mycmd -v jump JUMP! JUMP! JUMP!
Commands can take subcommand and suboptions. To do this simply add a module to your class with the same name as the subcommand, in which the suboption methods are defined.
MyCmd << Console::Command def initialize @height = 1 end def _v $VERBOSE = true end def jump if $VERBOSE puts "JUMP!" * @height else puts "Jump" * @height end end module Jump def __height(h) @height = h.to_i end end end MyCmd.start
Then on the command line:
% mycmd jump -h 2 Jump Jump % mycmd -v jump -h 3 JUMP! JUMP! JUMP!
Another thing to notice about this example is that start is an alias for execute.
You can use method_missing to catch missing subcommand calls.
If your command does not take subcommands then simply define a main method to dispatch action. All options will be treated globablly in this case and any remaining comman-line arguments will be passed to main.
If on the other hand your command does take subcommands but none is given, the default method will be called, if defined. If not defined an error will be raised (but only reported if $DEBUG is true).
You can define global options which are options that will be processed no matter where they occur in the command line. In the above examples only the options occuring before the subcommand are processed globally. Anything occuring after the subcommand belonds strictly to the subcommand. For instance, if we had added the following to the above example:
global_option :_v
Then -v could appear anywhere in the command line, even on the end, and still work as expected.
% mycmd jump -h 3 -v
You can use option_missing to catch any options that are not explicility defined.
The method signature should look like:
option_missing(option_name, args)
Example:
def option_missing(option_name, args) p args if $debug case option_name when 'p' @a = args[0].to_i @b = args[1].to_i 2 else raise InvalidOptionError(option_name, args) end end
Its return value should be the effective "arity" of that options — that is, how many arguments it consumed ("-p a b", for example, would consume 2 args: "a" and "b"). An arity of 1 is assumed if nil or false is returned.
Be aware that when using subcommand modules, the same option_missing method will catch missing options for global options and subcommand options too unless an option_missing method is also defined in the subcommand module.
execute | -> | start |