class NumRu::Misc::KeywordOpt

Attributes

description[R]

protected methods #####

val[R]

protected methods #####

Public Class Methods

new(*args) click to toggle source
# File lib/numru/misc/keywordopt.rb, line 211
def initialize(*args)
  # USAGE:
  #    KeywordOpt.new([key,val,description],[key,val,description],..)
  #    where key is a String, and description can be omitted.
  @val=Hash.new
  @description=Hash.new
  @keys = []
  args.each{ |x|
    case x
    when Array
      unless (x[0]=='help') && @keys.include?(x[0])
        #^only 'help' can overwrap in the arguments
        @keys.push(x[0])
        @val[x[0]] = x[1]
        @description[x[0]] = ( (x.length>=3) ? x[2] : '' )
      end
    when KeywordOpt
      x.keys.each{|k|
        unless k=='help' && @keys.include?(k)
          #^only 'help' can overwrap in the arguments
          @keys.push(k)
          @val[k] = x  #.val[k]
          @description[k] = x.description[k]
        end
      }
      def @val.[](k)
        val = super(k)
        val.is_a?(KeywordOpt) ? val[k] : val
      end
      def @val.dup
        out = Hash.new
        each{|k,val| out[k] = (val.is_a?(KeywordOpt) ? val[k] : val)}
        out
      end
    else
      raise ArgumentError, "invalid argument: #{x.inspect}"
    end
  }
  @keys_sort = @keys.sort
  if @keys_sort.length != @keys_sort.uniq.length
    raise ArgumentError, "keys are not unique"
  end
end

Public Instance Methods

[](k) click to toggle source
# File lib/numru/misc/keywordopt.rb, line 352
def [](k)
  v = @val[k]
  if v.is_a?(KeywordOpt)
    v = v.val[k]
  end
  v
end
help() click to toggle source
# File lib/numru/misc/keywordopt.rb, line 345
def help
   "  option name\tdefault value\t# description:\n" +
   @keys.collect{|k| 
     __line_feed("  #{k.inspect}\t#{@val[k].inspect}\t# #{@description[k]}", 66)
   }.join("\n")
end
interpret(hash) click to toggle source
# File lib/numru/misc/keywordopt.rb, line 255
def interpret(hash)
  return @val.dup if hash.nil?
  ##
  len = @val.length
  im = 0
  out = @val.dup
  hash.keys.sort.each do |key|
    rkey = /^#{key}/
    loop do
      if rkey =~ @keys_sort[im]
        if im<len-1 && rkey=~@keys_sort[im+1] &&
           key != @keys_sort[im]   # not identical
          raise ArgumentError, "Ambiguous key specification '#{key}'." 
        end
        out[@keys_sort[im]]=hash[key]
        break
      end
      im += 1
      if im==len
        raise ArgumentError, "'#{key}' does not match any of the keys."
      end
    end
  end
  out
end
keys() click to toggle source
# File lib/numru/misc/keywordopt.rb, line 360
def keys
  @keys.dup
end
select_existent(hash_or_keys) click to toggle source
# File lib/numru/misc/keywordopt.rb, line 281
def select_existent(hash_or_keys)
  hash_or_keys = hash_or_keys.dup         # not to alter the original
  len = @val.length
  im = 0
  kys = ( Array === hash_or_keys ? hash_or_keys : hash_or_keys.keys )
  kys.sort.each do |key|
    rkey = /^#{key}/
    loop do
      break if rkey =~ @keys_sort[im]
      im += 1
      if im==len
        hash_or_keys.delete(key)
        im = 0           # rewind
        break
      end
    end
  end
  hash_or_keys
end
set(hash) click to toggle source
# File lib/numru/misc/keywordopt.rb, line 301
def set(hash)
  raise ArgumentError, "not a hash" if !hash.is_a?(Hash)
  ##
  replaced = Hash.new
  len = @val.length
  im = 0
  hash.keys.sort.each do |key|
    rkey = /^#{key}/
    loop do
      if rkey =~ @keys_sort[im]
        if im<len-1 && rkey=~@keys_sort[im+1]
          raise "Ambiguous key specification '#{key}'." 
        end
        replaced[@keys_sort[im]] = @val[@keys_sort[im]]
        @val[@keys_sort[im]]=hash[key]
        break
      end
      im += 1
      raise "'#{key}' does not match any of the keys." if im==len
    end
  end
  replaced
end

Private Instance Methods

__line_feed(str, len) click to toggle source

def #__line_feed(str)

if str.length >= 68
  idx = str[0..67].rindex(/\s/)
  if idx
    str[idx, 1] = "\n\t" 
  end
end
str

end

# File lib/numru/misc/keywordopt.rb, line 334
def __line_feed(str, len)
  if str.length >= len
    idx = str[0...len].rindex(/\s/)
    if idx
      str = str[0...idx] + "\n\t\t\t# " + __line_feed(str[(idx+1)..-1],50)
    end
  end
  str
end