Module: Tins::GO
- Defined in:
- lib/tins/go.rb
Overview
A command-line option parsing library that provides a flexible way to parse single-character options with optional arguments. It supports multiple values for the same flag and provides a clean API for handling command-line interfaces.
Defined Under Namespace
Modules: ArrayExtension
Class Method Summary collapse
-
.go(s, args = ARGV, defaults: {}) ⇒ Hash{String => Object}
Parses the argument array args, according to the pattern s, to retrieve the single character command line options from it.
Instance Method Summary collapse
-
#go(s, args = ARGV, defaults: {}) ⇒ Hash{String => Object}
private
Parses the argument array args, according to the pattern s, to retrieve the single character command line options from it.
Class Method Details
.go(s, args = ARGV, defaults: {}) ⇒ Hash{String => Object}
Parses the argument array args, according to the pattern s, to retrieve the single character command line options from it.
Pattern syntax:
- 'x': Boolean flag.
- 'x:': Option requiring an argument.
- '~x': Explicitly disables the -x option.
Note: If a character is defined as both a boolean and a value flag (e.g., 'xx:'), it is considered ambiguous and will be disabled.
Behavior:
- If a value flag is missing its argument, or the next argument starts with '-', a warning is issued to STDERR and the flag is not set.
- This method modifies the args array in-place, removing all parsed options and leaving only the remaining positional arguments.
The defaults argument specifies default values for the options.
An option hash is returned with all found options set to a truthy value
representing the number of times they were encountered, or false if not
present. When a default value is specified and the flag is not present,
the default value is used instead.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/tins/go.rb', line 99 def go(s, args = ARGV, defaults: {}) d = defaults || {} b, v = s.scan(/(.)(:?)/).inject([ {}, {} ]) { |t, (o, a)| a = a == ?: t[a ? 1 : 0][o] = a ? nil : false t } (b.keys & v.keys).each do |o| warn "Warning: Option #{o} passed as boolean and value flag! => Ignoring #{o.inspect}." b.delete(o) v.delete(o) end b.each_key do |k| d.key?(k) or next if [ 0, false, nil ].include?(d[k]) b[k] = false elsif d[k].respond_to?(:to_int) b[k] = d[k].to_int else b[k] = 1 end end v.each_key do |k| d.key?(k) or next if [ 0, false, nil ].include?(d[k]) v[k] = nil else v[k] = d[k].to_s end end r = [] while a = args.shift /\A-(?<p>.+)/ =~ a or (r << a; next) until p == '' o = p.slice!(0, 1) if v.key?(o) if p.empty? && args.empty? warn "Warning: Option -#{o} requires an argument, but none was provided." r << a break 1 elsif p == '' an = args.first if an =~ /\A-/ warn "Warning: Option -#{o} requires an argument, but #{an.inspect} is not a valid value." r << a break end a = args.shift else a = p end if v[o].nil? || !(ArrayExtension === v[o]) a = a.dup a.extend ArrayExtension a.push a v[o] = a else v[o].push a end break elsif b.key?(o) if b[o] b[o] += 1 else b[o] = 1 end else r << a end end && break end r.reject! { |a| (b[p] = false) || true if /\A~(?<p>.)/ =~ a } v.transform_values! do |w| if w.is_a?(String) && !w.is_a?(ArrayExtension) w = w.dup w.extend ArrayExtension w.push w else w end end args.replace r b.merge(v) end |
Instance Method Details
#go(s, args = ARGV, defaults: {}) ⇒ Hash{String => Object} (private)
Parses the argument array args, according to the pattern s, to retrieve the single character command line options from it.
Pattern syntax:
- 'x': Boolean flag.
- 'x:': Option requiring an argument.
- '~x': Explicitly disables the -x option.
Note: If a character is defined as both a boolean and a value flag (e.g., 'xx:'), it is considered ambiguous and will be disabled.
Behavior:
- If a value flag is missing its argument, or the next argument starts with '-', a warning is issued to STDERR and the flag is not set.
- This method modifies the args array in-place, removing all parsed options and leaving only the remaining positional arguments.
The defaults argument specifies default values for the options.
An option hash is returned with all found options set to a truthy value
representing the number of times they were encountered, or false if not
present. When a default value is specified and the flag is not present,
the default value is used instead.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/tins/go.rb', line 99 def go(s, args = ARGV, defaults: {}) d = defaults || {} b, v = s.scan(/(.)(:?)/).inject([ {}, {} ]) { |t, (o, a)| a = a == ?: t[a ? 1 : 0][o] = a ? nil : false t } (b.keys & v.keys).each do |o| warn "Warning: Option #{o} passed as boolean and value flag! => Ignoring #{o.inspect}." b.delete(o) v.delete(o) end b.each_key do |k| d.key?(k) or next if [ 0, false, nil ].include?(d[k]) b[k] = false elsif d[k].respond_to?(:to_int) b[k] = d[k].to_int else b[k] = 1 end end v.each_key do |k| d.key?(k) or next if [ 0, false, nil ].include?(d[k]) v[k] = nil else v[k] = d[k].to_s end end r = [] while a = args.shift /\A-(?<p>.+)/ =~ a or (r << a; next) until p == '' o = p.slice!(0, 1) if v.key?(o) if p.empty? && args.empty? warn "Warning: Option -#{o} requires an argument, but none was provided." r << a break 1 elsif p == '' an = args.first if an =~ /\A-/ warn "Warning: Option -#{o} requires an argument, but #{an.inspect} is not a valid value." r << a break end a = args.shift else a = p end if v[o].nil? || !(ArrayExtension === v[o]) a = a.dup a.extend ArrayExtension a.push a v[o] = a else v[o].push a end break elsif b.key?(o) if b[o] b[o] += 1 else b[o] = 1 end else r << a end end && break end r.reject! { |a| (b[p] = false) || true if /\A~(?<p>.)/ =~ a } v.transform_values! do |w| if w.is_a?(String) && !w.is_a?(ArrayExtension) w = w.dup w.extend ArrayExtension w.push w else w end end args.replace r b.merge(v) end |