Class: OptConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/optconfig.rb

Defined Under Namespace

Classes: AmbiguousOption, ArgumentRequired, DuplicatedOption, Error, InvalidArgument, Option, UnknownOption, UnnecessaryArgument

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(default_attr = {}) ⇒ OptConfig

初期化

default_attr には各オプション属性のデフォルト値を Hash で指定可能。 オプション属性以外にも以下のものを指定できる。これらは OptConfig オブジェクト自身に影響する。

:file

オプションファイル名 (String)。デフォルト: なし。

:section

オプションファイル名のセクション名 (String または String の配列)。デフォルト: なし。

:ignore_unknown_file_option

オプションファイル内に未知のオプションがあっtた時に無視するか(true)エラーにするか(false)。デフォルト: true。

:stop_at_non_option_argument

オプションでない引数でオプションの解釈をやめるか(true)、それ以降もオプションの解釈を続けるか(false)。デフォルト: false。



142
143
144
145
146
147
148
149
150
151
152
# File 'lib/optconfig.rb', line 142

def initialize(default_attr={})
  @default_attr = default_attr
  @option_seq = []
  @options = {}
  @file = default_attr[:file]
  @section = default_attr[:section] && [default_attr[:section]].flatten
  @stop_at_non_option_argument = default_attr[:stop_at_non_option_argument]
  @ignore_unknown_file_option = default_attr.key?(:ignore_unknown_file_option) ? default_attr[:ignore_unknown_file_option] : true
  @obsolete_behavior = false
  @specified = {}               # オプションが指定されたかどうかを保持
end

Instance Attribute Details

#fileObject

Returns the value of attribute file.



153
154
155
# File 'lib/optconfig.rb', line 153

def file
  @file
end

#ignore_unknown_file_optionObject

Returns the value of attribute ignore_unknown_file_option.



153
154
155
# File 'lib/optconfig.rb', line 153

def ignore_unknown_file_option
  @ignore_unknown_file_option
end

#sectionObject Also known as: idlist

Returns the value of attribute section.



153
154
155
# File 'lib/optconfig.rb', line 153

def section
  @section
end

Instance Method Details

#[](name) ⇒ Object

オプションの値を返す

name

オプション名

例外

UnknownOption

Raises:



292
293
294
295
# File 'lib/optconfig.rb', line 292

def [](name)
  raise UnknownOption, "unknown option: #{name}" unless @options.key? name
  @options[name].value
end

#option(*args) ⇒ Object

オプション定義

args

オプション名(String) のリスト、オプションの属性(Hash)

戻り値

Option オブジェクト

例外

RuntimeError

オプションが既に定義されている



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/optconfig.rb', line 164

def option(*args)
  args = args.dup
  if args.last.is_a? Hash
    attr = args.pop
    attr = @default_attr.merge attr
  else
    attr = @default_attr
  end
  args.push attr
  opt = Option.new *args
  opt.name.each do |n|
    raise "option #{n} is already defined" if @options.key? n
    @options[n] = opt
  end
  @option_seq << opt
end

#options=(option) ⇒ Object

オプション定義(古いインタフェース)

option

オプション定義(ハッシュ)



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/optconfig.rb', line 183

def options=(option)
  @options.clear
  @option_seq.clear
  option.each do |k,v|
    v = [v] unless v.is_a? Array
    arg = k.is_a?(Array) ? k : [k]
    arg.push({:format=>v[0], :default=>v[1]})
    opt = Option.new *arg
    opt.name.each do |n|
      raise "option #{n} is already defined" if @options.key? n
      @options[n] = opt
    end
    @option_seq << opt
  end
  @obsolete_behavior = true
  option
end

#parse(argv = []) ⇒ Object

argv のオプションを解析する

argv

文字列の配列

戻り値

argv からオプションを取り除いたもの



252
253
254
# File 'lib/optconfig.rb', line 252

def parse(argv=[])
  parse!(argv.dup)
end

#parse!(argv = []) ⇒ Object

argv のオプションを解析し、オプションを取り除いたものに置き換える

argv

配列

戻り値

argv

残りの引数



205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/optconfig.rb', line 205

def parse!(argv=[])
  orig_argv_size = argv.size
  ret = []
  @specified.clear
  @option_seq.each do |opt|
    opt.value = opt.ovalue = opt.default
    begin
      opt.value = check_option opt.name.first, opt.default if opt.default.is_a? String
    rescue OptConfig::Error
      # 無視
    end
  end
  parse_file @file if @file
  @specified.clear

  until argv.empty?
    arg = argv.shift
    case arg
    when "--"
      ret.concat argv
      break
    when /\A--[a-zA-Z0-9_]/
      parse_long_opt arg.sub(/\A--/, ""), argv
    when /\A-[a-zA-Z0-9]/
      parse_short_opt arg.sub(/\A-/, ""), argv
    else
      ret.push arg
      if @stop_at_non_option_argument
        ret.concat argv
        break
      end
    end
  end

  if @obsolete_behavior
    n = orig_argv_size - ret.size
    argv.replace ret
    return n
  end
  argv.replace ret
  return argv
end

#parse_file(filename) ⇒ Object

ファイルからオプションを読み込む

filename

ファイル名

例外

UnknownOption



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
# File 'lib/optconfig.rb', line 260

def parse_file(filename)
  cur_sect = nil
  File.open filename do |f|
    f.each_line do |line|
      line.chomp!
      next if line =~ /\A#|\A\s*\z/
      if line =~ /\A\[(.*)\]\z/
        cur_sect = $1
        next
      end
      if @section.nil? or @section.empty? or @section.include? cur_sect
        name, value = line.split(/\s*=\s*|\s+/, 2)
        begin
          name, = long_option name, false
          raise UnknownOption, "unknown option: #{name}" unless @options[name].in_config
          if value
            parse_long_opt "#{name}=#{value}", [], false
          else
            parse_long_opt name, [], false
          end
        rescue UnknownOption
          raise unless @ignore_unknown_file_option
        end
      end
    end
  end
end

#usageObject

オプションの説明文字列を返す



298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/optconfig.rb', line 298

def usage
  ret = ""
  @option_seq.each do |opt|
    next unless opt.description
    short = []
    long = []
    opt.usage_name.each do |n|
      if n.size == 1
        short << "-#{n}"
      else
        long << "--#{n}"
      end
    end
    line = "  "+(short+long).join(", ")
    if opt.description.empty?
      ret << line+"\n"
      next
    end
    if line.length >= 25
      line << "\n                          "
    else
      line << " "*(26-line.length)
    end
    desc = opt.description.gsub(/%s/, opt.ovalue.to_s).split "\n"
    line << desc.shift+"\n"
    desc.each do |d|
      line << "                          #{d}\n"
    end
    ret << line
  end
  ret
end