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. 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

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

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

Options and subcommands can be accessed using #[]

The following methods are created dynamically for each declared option with an attribute name

def <identifier>(default = nil) self["<identifier>"] || default end
def <identifier>=(value) self["<identifier>"] = value end
def <identifier>?() self.key?("<identifier>") end

Options without an an attribute can still be accessed using #[] or trough #__options__ 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

Program

Constant Summary collapse

RESERVED_OPTION_NAMES =

These names can’t be used as option or command names

%w(
is_a
instance_eval instance_exec method_missing singleton_method_added
singleton_method_removed singleton_method_undefined)
OVERRIDEABLE_METHODS =

These methods can be overridden by an option (the value is not used - this is just for informational purposes)

%w(
    subcommand
)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#__grammar__Object (readonly)

Grammar object



150
151
152
# File 'lib/shellopts/program.rb', line 150

def __grammar__
  @__grammar__
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



162
163
164
# File 'lib/shellopts/program.rb', line 162

def __option_list__
  @__option_list__
end

#__options__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 the value, with arguments the value is an array of the given values



156
157
158
# File 'lib/shellopts/program.rb', line 156

def __options__
  @__options__
end

#__supercommand__Object

The parent command or nil. Initialized by #add_command



138
139
140
# File 'lib/shellopts/program.rb', line 138

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__



56
57
58
59
60
# File 'lib/shellopts/program.rb', line 56

def self.new(grammar)
  object = super()
  object.__send__(:__initialize__, grammar)
  object
end

Instance Method Details

#[](key) ⇒ Object

Return command object or option argument value if present, otherwise nil

The key is the name or identifier of the object or any any option alias. Eg. :f, ‘-f’, :file, or ‘–file’ are all usable as option keys and :cmd! or ‘cmd’ as command keys

For options, the returned value is the argument given by the user optionally converted to Integer or Float or nil if the option doesn’t take arguments. If the option takes an argument and it is repeatable the value is an array of the arguments. Repeatable options without arguments have the number of occurences as the value



74
75
76
77
78
79
80
81
82
83
# File 'lib/shellopts/program.rb', line 74

def [](key)
  case object = __grammar__[key]
    when ::ShellOpts::Grammar::Command
      object.ident == __subcommand__!.__ident__ ? __subcommand__! : nil
    when ::ShellOpts::Grammar::Option
      __options__[object.ident]
    else
      nil
  end
end

#[]=(key, value) ⇒ Object

Assign a value to an existing option. This can be used to implement default values. #[]= doesn’t currently check the type of the given value so take care. Note that the corresponding option(s) in #option_list is not updated



89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/shellopts/program.rb', line 89

def []=(key, value)
  case object = __grammar__[key]
    when ::ShellOpts::Grammar::Command
      ::Kernel.raise ArgumentError, "#{key.inspect} is not an option"
    when ::ShellOpts::Grammar::Option
      object.argument? || object.repeatable? or
          ::Kernel.raise ArgumentError, "#{key.inspect} is not assignable"
      __options__[object.ident] = value
    else
      ::Kernel.raise ArgumentError, "Unknown option or command: #{key.inspect}"
  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 {
    __options__.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)



144
# File 'lib/shellopts/program.rb', line 144

def __ident__() @__grammar__.ident end

#__name__Object

Name of command/program without the exclamation mark (String)



147
# File 'lib/shellopts/program.rb', line 147

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



167
# File 'lib/shellopts/program.rb', line 167

def __subcommand__() @__subcommand__&.__ident__ end

#__subcommand__!Object

The actual subcommand object or nil if not present



170
# File 'lib/shellopts/program.rb', line 170

def __subcommand__!() @__subcommand__ end

#__uid__Object

UID of command/program



141
# File 'lib/shellopts/program.rb', line 141

def __uid__() @__grammar__.uid end

#key?(key) ⇒ Boolean

Return true if the given command or option is present

Returns:

  • (Boolean)


103
104
105
106
107
108
109
110
111
112
# File 'lib/shellopts/program.rb', line 103

def key?(key)
  case object = __grammar__[key]
    when ::ShellOpts::Grammar::Command
      object.ident == __subcommand__!.ident ? __subcommand__! : nil
    when ::ShellOpts::Grammar::Option
      __options__.key?(object.ident)
    else
      nil
  end
end

#subcommandObject

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



125
# File 'lib/shellopts/program.rb', line 125

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



135
# File 'lib/shellopts/program.rb', line 135

def subcommand!() __subcommand__! end