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

Program

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! supercommand!
)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#__grammar__Object (readonly)

Grammar object



154
155
156
# File 'lib/shellopts/program.rb', line 154

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



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

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



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

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



160
161
162
# File 'lib/shellopts/program.rb', line 160

def __option_values__
  @__option_values__
end

#__supercommand__Object

The parent command or nil. Initialized by #add_command



173
174
175
# File 'lib/shellopts/program.rb', line 173

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

#[](key) ⇒ Object

Return command or option object if present, otherwise nil. Returns a possibly empty array of option objects if the option is repeatable

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



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

def [](key)
  case object = __grammar__[key]
    when ::ShellOpts::Grammar::Command
      object.ident == __subcommand__!.__ident__ ? __subcommand__! : nil
    when ::ShellOpts::Grammar::Option
      if object.repeatable?
        __option_hash__[object.ident] || []
      else
        __option_hash__[object.ident]
      end
    else
      ::Kernel.raise ::ArgumentError, "Unknown command or option: '#{key}'"
  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)



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

def __ident__() @__grammar__.ident end

#__name__Object

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



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

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



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

def __subcommand__() @__subcommand__&.__ident__ end

#__subcommand__!Object

The actual subcommand object or nil if not present



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

def __subcommand__!() @__subcommand__ end

#__uid__Object

UID of command/program



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

def __uid__() @__grammar__.uid end

#key?(key) ⇒ Boolean

Return true if the given command or option is present

Returns:

  • (Boolean)


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

def key?(key)
  case object = __grammar__[key]
    when ::ShellOpts::Grammar::Command
      object.ident == __subcommand__
    when ::ShellOpts::Grammar::Option
      __option_hash__.key?(object.ident)
    else
      ::Kernel.raise ::ArgumentError, "Unknown command or option: '#{key}'"
  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



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

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



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

def subcommand!() __subcommand__! 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



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

def supercommand!() __supercommand__ end

#to_h(*keys) ⇒ Object

Returns a hash of the given options if defined. Returns all options if no options are given



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

def to_h(*keys)
  keys = ::Kernel::Array(keys).flatten
  if keys.empty?
    @__option_values__
  else
    keys.map { |key|
      @__option_values__.key?(key) ? [key, @__option_values__[key]] : nil
    }.compact.to_h
  end
end