Class: StringifyHash

Inherits:
Hash
  • Object
show all
Defined in:
lib/stringify-hash.rb

Overview

A hash that treats Symbol and String keys interchangeably and recursively merges hashes

Constant Summary collapse

DIV =

The dividor between elements when StringifyHash is dumped

'    '
EOL =

The end of line when dumping

"\n"

Instance Method Summary collapse

Instance Method Details

#[](k) ⇒ nil, Object

Get value for given key, search for both k as String and k as Symbol, if not present return nil

Examples:

Use this method to return the value for a given key

a['key'] = 'value'
a['key'] == a[:key] == 'value'

Parameters:

  • k (Object)

    The key to find, searches for both k as String and k as Symbol

Returns:

  • (nil, Object)

    Return the Object found at given key, or nil if no Object found



23
24
25
# File 'lib/stringify-hash.rb', line 23

def [] k
  super(k.to_s) || super(k.to_sym)
end

#[]=(k, v) ⇒ Object

Set Symbol key to Object value

Examples:

Use this method to set the value for a key

a['key'] = 'value'

Parameters:

  • k (Object)

    The key to associated with the value, converted to Symbol key

  • v (Object)

    The value to store in the ObjectHash

Returns:

  • (Object)

    Return the Object value just stored



36
37
38
# File 'lib/stringify-hash.rb', line 36

def []=k,v
  super(k.to_sym, v)
end

#as_coll(opening, closing, in_lvl, in_inc, &block) ⇒ Object

Helper for formatting collections Computes the indentation level for elements of the collection Yields indentation to block to so the caller can create map of element strings Places delimiters in the correct location Joins everything with correct EOL

!@visibility private



145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/stringify-hash.rb', line 145

def as_coll( opening, closing, in_lvl, in_inc, &block )
  delim_indent = in_inc * in_lvl
  elem_indent  = in_inc * (in_lvl + 1)

  open_brace  = opening
  close_brace = delim_indent + closing

  fmtd_coll = block.call( elem_indent )
  str_coll = fmtd_coll.join( ',' + EOL )

  return open_brace + EOL + str_coll + EOL + close_brace
end

#delete(k) ⇒ Object?

Determine key=>value entry in StringifyHash, remove both value at String key and value at Symbol key

deletes both k as String and k as Symbol

nil if no Object deleted

Examples:

Use this method to set the value for a key

a['key'] = 'value'
a.delete[:key] == 'value'

Parameters:

  • k (Object)

    The key to delete in ObjectHash,

Returns:

  • (Object, nil)

    The Object deleted at value,



65
66
67
# File 'lib/stringify-hash.rb', line 65

def delete k
  super(k.to_s) || super(k.to_sym)
end

#dumpString

Pretty print the options as JSON

Examples:

base = { :key => { :subkey1 => 'subval', :subkey2 => 'subval' } }
base.dump
#=>  '{
          "key": {
              "subkey1": "subval",
              "subkey2": 2
          }
      }

Returns:

  • (String)

    The description of self



295
296
297
# File 'lib/stringify-hash.rb', line 295

def dump
  fmt_collection( self, 0, DIV )
end

#fmt_assoc(coll, in_lvl = 0, in_inc = DIV) ⇒ String

Pretty prints an associative collection

Examples:

base = { :key => 'value', :key2 => 'value' }
self.fmt_assoc( base )
#=> '{
         "key": "value",
         "key2": "value"
     }'

Parameters:

  • coll (#each_pair)

    The collection to be printed

  • in_lvl (Integer) (defaults to: 0)

    The level of indentation

  • in_inc (String) (defaults to: DIV)

    The increment to indent

Returns:

  • (String)

    The collection as a pretty JSON object



202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/stringify-hash.rb', line 202

def fmt_assoc( coll, in_lvl = 0, in_inc = DIV )
  if coll.empty?
    return '{}'
  else
    as_coll '{', '}', in_lvl, in_inc do |elem_indent|
      coll.map do |key, value|
        assoc_line = elem_indent + '"' + key.to_s + '"' + ': '
        assoc_line += fmt_value( value, in_lvl, in_inc )
      end
    end
  end
end

#fmt_basic(value) ⇒ String

Pretty prints primitive JSON values

Examples:

self.fmt_value( 4 )
#=> '4'
self.fmt_value( true )
#=> 'true'
self.fmt_value( nil )
#=> 'null'
self.fmt_value( 'string' )
#=> '"string"'

Parameters:

  • value (Object)

    The collection to be printed

Returns:

  • (String)

    The value as a valid JSON primitive



274
275
276
277
278
279
280
# File 'lib/stringify-hash.rb', line 274

def fmt_basic( value )
  case value
  when Numeric, TrueClass, FalseClass then value.to_s
  when NilClass then "null"
  else "\"#{value}\""
  end
end

#fmt_collection(collection, in_lvl = 0, in_inc = DIV) ⇒ String

Pretty prints a collection

Examples:

base = {:key => { :subkey1 => 'subval', :subkey2 => ['subval'] }}
self.fmt_collection( base )
#=> '{
         "key": {
             "subkey": "subval",
             "subkey2": [
                 "subval"
             ]
         }
     }'

Parameters:

  • collection (Enumerable)

    The collection to be printed

  • in_lvl (Integer) (defaults to: 0)

    The level of indentation

  • in_inc (String) (defaults to: DIV)

    The increment to indent

Returns:

  • (String)

    The collection as a pretty JSON object



177
178
179
180
181
182
183
184
185
# File 'lib/stringify-hash.rb', line 177

def fmt_collection( collection, in_lvl = 0, in_inc = DIV )
  if collection.respond_to? :each_pair
    string = fmt_assoc( collection, in_lvl, in_inc )
  else
    string = fmt_list( collection, in_lvl, in_inc )
  end

  return string
end

#fmt_list(coll, in_lvl = 0, in_inc = DIV) ⇒ String

Pretty prints a list collection

Examples:

base = [ 'first', 'second' ]
self.fmt_list( base )
#=> '[
         "first",
         "second"
     ]'

Parameters:

  • coll (#each)

    The collection to be printed

  • in_lvl (Integer) (defaults to: 0)

    The level of indentation

  • in_inc (String) (defaults to: DIV)

    The increment to indent

Returns:

  • (String)

    The collection as a pretty JSON object



230
231
232
233
234
235
236
237
238
239
240
# File 'lib/stringify-hash.rb', line 230

def fmt_list( coll, in_lvl = 0, in_inc = DIV )
  if coll.empty?
    return '[]'
  else
    as_coll '[', ']', in_lvl, in_inc do |indent|
      coll.map do |el|
        indent + fmt_value( el, in_lvl, in_inc )
      end
    end
  end
end

#fmt_value(value, in_lvl = 0, in_inc = DIV) ⇒ Object

Chooses between collection and primitive formatting

!@visibility private



245
246
247
248
249
250
251
# File 'lib/stringify-hash.rb', line 245

def fmt_value( value, in_lvl = 0, in_inc = DIV )
  if value.kind_of? Enumerable and not value.is_a? String
    fmt_collection( value, in_lvl + 1, in_inc )
  else
    fmt_basic( value )
  end
end

#has_key?(k) ⇒ Boolean

Determine if key is stored in ObjectHash

Examples:

Use this method to set the value for a key

a['key'] = 'value'
a.has_key[:key] == true

Parameters:

  • k (Object)

    The key to find in ObjectHash, searches for both k as String and k as Symbol

Returns:

  • (Boolean)


49
50
51
# File 'lib/stringify-hash.rb', line 49

def has_key? k
  super(k.to_s) || super(k.to_sym)
end

#merge(hash) ⇒ StringifyHash

Create new StringifyHash from recursively merged self with an OptionsHash or Hash

Examples:

base = { :key => { :subkey1 => 'subval', :subkey2 => 'subval' } }
hash = { :key => { :subkey1 => 'newval'} }

base.merge(hash)
#=> {:key =>
      {:subkey1 => 'newval',
       :subkey2 => 'subval' }

Parameters:

Returns:



112
113
114
115
116
# File 'lib/stringify-hash.rb', line 112

def merge hash
  #make a deep copy into an empty hash object
  merged_hash = rmerge(StringifyHash.new, self)
  rmerge(merged_hash, hash)
end

#merge!(hash) ⇒ StringifyHash

Recursively merge self with an StringifyHash or Hash

Examples:

base = { :key => { :subkey1 => 'subval', :subkey2 => 'subval' } }
hash = { :key => { :subkey1 => 'newval'} }

base.merge!(hash)
#=> {:key =>
      {:subkey1 => 'newval',
       :subkey2 => 'subval' }

Parameters:

Returns:



132
133
134
# File 'lib/stringify-hash.rb', line 132

def merge! hash
  rmerge(self, hash)
end

#rmerge(base, hash) ⇒ StringifyHash

Recursively merge and StringifyHash with an OptionsHash or Hash

Examples:

base = { :key => { :subkey1 => 'subval', :subkey2 => 'subval' } }
hash = { :key => { :subkey1 => 'newval'} }

rmerge(base, hash)
#=>  {:key =>
        {:subkey1 => 'newval',
         :subkey2 => 'subval'}}

Parameters:

Returns:



84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/stringify-hash.rb', line 84

def rmerge base, hash
  return base unless hash.is_a?(Hash) || hash.is_a?(StringifyHash)
  hash.each do |key, v|
    if (base[key].is_a?(Hash) || base[key].is_a?(StringifyHash)) && (hash[key].is_a?(Hash) || hash[key].is_a?(OptionsHash))
      rmerge(base[key], hash[key])
    elsif hash[key].is_a?(Hash)
      base[key] = StringifyHash.new.merge(hash[key])
    else
      base[key]= hash[key]
    end
  end
  base
end