Class: ShellOpts::Command
- Inherits:
- BasicObject
- Defined in:
- lib/shellopts/program.rb,
lib/shellopts/dump.rb
Overview
Command represents a program or a subcommand. It is derived from BasicObject to have only a minimum of inherited member methods.
The names of the inherited methods can’t be used as options or command namess. They are: instance_eval, instance_exec method_missing, singleton_method_added, singleton_method_removed, and singleton_method_undefined.
Additional methods defined in Command use the ‘__<identifier>__’ naming convention that doesn’t collide with option or subcommand names but they’re rarely used in application code
Command also defines #subcommand and #subcommand! but they can be overshadowed by an option or command declaration. Their values can still be accessed using the dashed name, though
Option and Command objects can be accessed using #[]. #key? is also defined
The following methods are created dynamically for each declared option with an attribute name
<identifier>(default = nil)
<identifier>=(value)
<identifier>?()
The default value is used if the option or its value is missing
Options without an an attribute can still be accessed using #[] or trough #option_values, #__option_hash, or #options_list
Each subcommand has a single method:
# Return the subcommand object or nil if not present
def <identifier>!() subcommand == :<identifier> ? @__subcommand__ : nil end
The general #subcommand method can be used to find out which subcommand is used
Direct Known Subclasses
Constant Summary collapse
- RESERVED_OPTION_NAMES =
These names can’t be used as option or command names
%w( is_a to_h instance_eval instance_exec method_missing singleton_method_added singleton_method_removed singleton_method_undefined )
- OVERRIDEABLE_METHOD_NAMES =
These methods can be overridden by an option or a command (this constant is not used - it is just for informational purposes)
%w( subcommand subcommand! subcommands subcommands! supercommand! )
Instance Attribute Summary collapse
-
#__grammar__ ⇒ Object
readonly
Grammar object.
-
#__option_hash__ ⇒ Object
readonly
Map from identifier to option object or to a list of option objects if the option is repeatable.
-
#__option_list__ ⇒ Object
readonly
List of Option objects for the subcommand in the same order as given by the user but note that options are reordered to come after their associated subcommand if float is true.
-
#__option_values__ ⇒ Object
readonly
Hash from identifier to value.
-
#__supercommand__ ⇒ Object
The parent command or nil.
Class Method Summary collapse
-
.dump(expr, argv = []) ⇒ Object
Class-level accessor methods.
-
.new(grammar) ⇒ Object
Redefine ::new to call #__initialize__.
Instance Method Summary collapse
-
#[](uid) ⇒ Object
Returns the command or option object identified by the UID if present and otherwise nil.
- #__dump__(argv = []) ⇒ Object
-
#__ident__ ⇒ Object
Identfier including the exclamation mark (Symbol).
-
#__name__ ⇒ Object
Name of command/program without the exclamation mark (String).
-
#__subcommand__ ⇒ Object
The subcommand identifier (a Symbol incl. the exclamation mark) or nil if not present.
-
#__subcommand__! ⇒ Object
The actual subcommand object or nil if not present.
-
#__subcommands__ ⇒ Object
Implementation of the #subcommands method.
-
#__subcommands__! ⇒ Object
Implementation of the #subcommands! method.
-
#__uid__ ⇒ Object
UID of command/program (String).
-
#subcommand ⇒ Object
Subcommand identifier or nil if not present.
-
#subcommand! ⇒ Object
The subcommand object or nil if not present.
-
#subcommands ⇒ Object
Returns the concatenated identifier of subcommands (eg. :cmd.subcmd!).
-
#subcommands! ⇒ Object
Returns the subcommands in an array.
-
#supercommand! ⇒ Object
The parent command or nil.
-
#to_h(*keys) ⇒ Object
Returns a hash from option ident to value.
-
#to_h?(*keys) ⇒ Boolean
Like #to_h but present options without arguments have a true value.
Instance Attribute Details
#__grammar__ ⇒ Object (readonly)
Grammar object
157 158 159 |
# File 'lib/shellopts/program.rb', line 157 def __grammar__ @__grammar__ end |
#__option_hash__ ⇒ Object (readonly)
Map from identifier to option object or to a list of option objects if the option is repeatable
173 174 175 |
# File 'lib/shellopts/program.rb', line 173 def __option_hash__ @__option_hash__ end |
#__option_list__ ⇒ Object (readonly)
List of Option objects for the subcommand in the same order as given by the user but note that options are reordered to come after their associated subcommand if float is true. Repeated options are not collapsed
169 170 171 |
# File 'lib/shellopts/program.rb', line 169 def __option_list__ @__option_list__ end |
#__option_values__ ⇒ Object (readonly)
Hash from identifier to value. Can be Integer, Float, or String depending on the option’s type. Repeated options options without arguments have the number of occurences as value, repeated option with arguments have the array of values as value
163 164 165 |
# File 'lib/shellopts/program.rb', line 163 def __option_values__ @__option_values__ end |
#__supercommand__ ⇒ Object
The parent command or nil. Initialized by #add_command
176 177 178 |
# File 'lib/shellopts/program.rb', line 176 def __supercommand__ @__supercommand__ end |
Class Method Details
.dump(expr, argv = []) ⇒ Object
Class-level accessor methods
149 |
# File 'lib/shellopts/dump.rb', line 149 def self.dump(expr, argv = []) expr.__dump__(argv) end |
.new(grammar) ⇒ Object
Redefine ::new to call #__initialize__
59 60 61 62 63 |
# File 'lib/shellopts/program.rb', line 59 def self.new(grammar) object = super() object.__send__(:__initialize__, grammar) object end |
Instance Method Details
#[](uid) ⇒ Object
Returns the command or option object identified by the UID if present and otherwise nil. Returns a possibly empty array of option objects if the option is repeatable. Raise an ArgumentError if the key doesn’t exists
The key
is the symbolic UID of the object. Eg. :command.option or :command.subcommand!
72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/shellopts/program.rb', line 72 def [](uid) __grammar__.key?(uid) or ::Kernel.raise ::ArgumentError, "'#{uid}' is not a valid UID" idents = uid.to_s.gsub(/\./, "!.").split(/\./).map(&:to_sym) idents.inject(self) { |cmd, ident| case ident.to_s when /!$/ return nil if cmd.__subcommand__ != ident cmd = cmd.__subcommand__! else opt = cmd.__option_hash__[ident] opt.nil? && cmd.__grammar__[ident].repeatable? ? [] : opt end } end |
#__dump__(argv = []) ⇒ Object
139 140 141 142 143 144 145 146 |
# File 'lib/shellopts/dump.rb', line 139 def __dump__(argv = []) ::Kernel.puts __name__ ::Kernel.indent { .each { |ident, value| ::Kernel.puts "#{ident}: #{value.inspect}" } __subcommand__!&.__dump__ ::Kernel.puts argv.map(&:inspect).join(" ") if !argv.empty? } end |
#__ident__ ⇒ Object
Identfier including the exclamation mark (Symbol)
151 |
# File 'lib/shellopts/program.rb', line 151 def __ident__() @__grammar__.ident end |
#__name__ ⇒ Object
Name of command/program without the exclamation mark (String)
154 |
# File 'lib/shellopts/program.rb', line 154 def __name__() @__grammar__.name end |
#__subcommand__ ⇒ Object
The subcommand identifier (a Symbol incl. the exclamation mark) or nil if not present. Use #subcommand!, or the dynamically generated ‘#<identifier>!’ method to get the actual subcommand object
181 |
# File 'lib/shellopts/program.rb', line 181 def __subcommand__() @__subcommand__&.__ident__ end |
#__subcommand__! ⇒ Object
The actual subcommand object or nil if not present
184 |
# File 'lib/shellopts/program.rb', line 184 def __subcommand__!() @__subcommand__ end |
#__subcommands__ ⇒ Object
Implementation of the #subcommands method
187 188 189 |
# File 'lib/shellopts/program.rb', line 187 def __subcommands__() __subcommands__!.last&.__uid__&.to_sym end |
#__subcommands__! ⇒ Object
Implementation of the #subcommands! method
192 193 194 |
# File 'lib/shellopts/program.rb', line 192 def __subcommands__!() ::Algorithm.follow(self.__subcommand__!, :__subcommand__!).to_a end |
#__uid__ ⇒ Object
UID of command/program (String)
148 |
# File 'lib/shellopts/program.rb', line 148 def __uid__() @__grammar__.uid end |
#subcommand ⇒ Object
Subcommand identifier or nil if not present. #subcommand is often used in case statement to branch out to code that handles the given subcommand:
prog, args = ShellOpts.parse("do_this! do_that!", ARGV)
case prog.subcommand
when :do_this!; prog.do_this.operation # or prog[:subcommand!] or prog.subcommand!
when :do_that!; prog.do_that.operation
end
Note: Can be overridden by option, in that case use #__subcommand__ or ShellOpts.subcommand(object) instead
120 |
# File 'lib/shellopts/program.rb', line 120 def subcommand() __subcommand__ end |
#subcommand! ⇒ Object
The subcommand object or nil if not present. Per-subcommand methods (#<identifier>!) are often used instead of #subcommand! to get the subcommand
Note: Can be overridden by a subcommand declaration (but not an option), in that case use #__subcommand__! or ShellOpts.subcommand!(object) instead
130 |
# File 'lib/shellopts/program.rb', line 130 def subcommand!() __subcommand__! end |
#subcommands ⇒ Object
Returns the concatenated identifier of subcommands (eg. :cmd.subcmd!)
133 |
# File 'lib/shellopts/program.rb', line 133 def subcommands() __subcommands__ end |
#subcommands! ⇒ Object
Returns the subcommands in an array. This doesn’t include the top-level program object
137 |
# File 'lib/shellopts/program.rb', line 137 def subcommands!() __subcommands__! end |
#supercommand! ⇒ Object
The parent command or nil. Initialized by #add_command
Note: Can be overridden by a subcommand declaration (but not an option), in that case use #__supercommand__! or ShellOpts.supercommand!(object) instead
145 |
# File 'lib/shellopts/program.rb', line 145 def supercommand!() __supercommand__ end |
#to_h(*keys) ⇒ Object
Returns a hash from option ident to value
The value depends on the option type: If it is not repeatable, the value is the argument or nil if not present (or allowed). If the option is repeatable and has an argument, the value is an array of the arguments, if it doesn’t have an argument, the value is the number of occurrences
94 95 96 97 |
# File 'lib/shellopts/program.rb', line 94 def to_h(*keys) keys = ::Kernel::Array(keys).flatten __option_values__.select { |key,_| keys.empty? || keys.include?(key) } end |
#to_h?(*keys) ⇒ Boolean
Like #to_h but present options without arguments have a true value
101 102 103 104 105 |
# File 'lib/shellopts/program.rb', line 101 def to_h?(*keys) keys = ::Kernel::Array(keys).flatten keys = keys.empty? ? __option_values__.keys : keys keys.filter_map { |key| __option_values__.key?(key) && [key, self.__send__(key)] }.to_h end |