Sha256: c979e728fcb626700f5e6711e0e6a8bf77ea306f30f8a66d9588582be09ea87a

Contents?: true

Size: 1.9 KB

Versions: 1

Compression:

Stored size: 1.9 KB

Contents

require 'date'
require 'uri'

class HashStruct < Hash

  def initialize(args={})
    super()
    args.each { |key, value| self[key] = value }
  end

  def [](key)
    key = make_key(key)
    has_key?(key) ? fetch(key) : nil
  end

  def []=(key, value)
    store(make_key(key), convert_object(value))
  end

  def method_missing(method_id, *args)
    method_name = method_id.to_s
    if method_name =~ /=$/
      raise ArgumentError, "wrong number of arguments for method #{method_name.inspect} (#{args.length} for 1)", caller(1) if args.length != 1
      raise TypeError, "can't modify frozen #{self.class}", caller(1) if self.frozen?
      self[method_name.chop] = args.first
    else
      raise ArgumentError, "wrong number of arguments (#{args.length} for 0)", caller(1) if args.length != 0
      self[method_id]
    end
  end

  def make_key(obj)
    obj.to_s.downcase.to_sym
  end

  def convert_object(obj)
    case obj
    when String
      case obj
      # URI
      when %r{^(ftp|http|https|mailto):}
        URI.parse(obj) rescue obj
      # integer
      when %r{^-?[1-9][\d,]*$}
        obj.gsub(/,/, '').to_i
      # hex integer
      when %r{^0x[0-9a-f]+$}i
        obj.hex
      # float
      when %r{^-?[\d,]+\.\d+$}
        obj.gsub(/,/, '').to_f
      # percent
      when %r{^-?[\d,]+(\.\d+)?%$}
        obj.to_f / 100
      # rational
      when %r{^(\d+)/(\d+)$}
        Rational($1.to_i, $2.to_i)
      # date
      when %r{^\d{4}-\d{2}-\d{2}$},      # 2010-06-06
           %r{^\d{1,2}/\d{1,2}/\d{4}$},  # 06/06/2010
           %r{^\d{4}/\d{1,2}/\d{1,2}$}   # 2010/06/06
        Date.parse(obj)
      # boolean true
      when 'true', 'yes', 'on'
        true
      # boolean false
      when 'false', 'no', 'off'
        false
      else
        obj
      end
    when Array
      obj.map { |o| convert_object(o) }
    when Hash
      HashStruct.new(obj)
    when HashStruct
      obj
    else
      obj
    end
  end

end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
hashstruct-1.4 lib/hashstruct.rb