Class: Lotus::Utils::Hash

Inherits:
Object
  • Object
show all
Defined in:
lib/lotus/utils/hash.rb

Overview

Hash on steroids

Since:

  • 0.1.0

Constant Summary collapse

DUPLICATE_LOGIC =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

See Also:

Since:

  • 0.6.0

Proc.new do |value|
  case value
  when Hash
    value.deep_dup
  when ::Hash
    Hash.new(value).deep_dup.to_h
  end
end.freeze

Instance Method Summary collapse

Constructor Details

#initialize(hash = {}, &blk) ⇒ Lotus::Utils::Hash

Initialize the hash

Examples:

Passing a Hash

require 'lotus/utils/hash'

hash = Lotus::Utils::Hash.new('l' => 23)
hash['l'] # => 23

Passing a block for default

require 'lotus/utils/hash'

hash = Lotus::Utils::Hash.new {|h,k| h[k] = [] }
hash['foo'].push 'bar'

hash.to_h # => { 'foo' => ['bar'] }

Parameters:

  • hash (#to_h) (defaults to: {})

    the value we want to use to initialize this instance

  • blk (Proc)

    define the default value

See Also:

Since:

  • 0.1.0



46
47
48
49
# File 'lib/lotus/utils/hash.rb', line 46

def initialize(hash = {}, &blk)
  @hash = hash.to_h
  @hash.default_proc = blk
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &blk) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Override Ruby’s method_missing in order to provide ::Hash interface

Raises:

  • (NoMethodError)

    If doesn’t respond to the given method

Since:

  • 0.3.0



280
281
282
283
284
285
286
287
288
# File 'lib/lotus/utils/hash.rb', line 280

def method_missing(m, *args, &blk)
  if respond_to?(m)
    h = @hash.__send__(m, *args, &blk)
    h = self.class.new(h) if h.is_a?(::Hash)
    h
  else
    raise NoMethodError.new(%(undefined method `#{ m }' for #{ @hash }:#{ self.class }))
  end
end

Instance Method Details

#==(other) ⇒ TrueClass, FalseClass Also known as: eql?

Equality

Returns:

  • (TrueClass, FalseClass)

Since:

  • 0.3.0



250
251
252
# File 'lib/lotus/utils/hash.rb', line 250

def ==(other)
  @hash == other.to_h
end

#[](key) ⇒ Object?

Retrieves the value object corresponding to the key object.

Parameters:

  • key (Object)

    the key

Returns:

  • (Object, nil)

    the correspoding value, if present

See Also:

Since:

  • 0.3.0



202
203
204
# File 'lib/lotus/utils/hash.rb', line 202

def [](key)
  @hash[key]
end

#[]=(key, value) ⇒ Object

Associates the value given by value with the key given by key.

Parameters:

  • key (Object)

    the key to assign

  • value (Object)

    the value to assign

See Also:

Since:

  • 0.3.0



214
215
216
# File 'lib/lotus/utils/hash.rb', line 214

def []=(key, value)
  @hash[key] = value
end

#deep_dupHash

Return a deep copy of the current Lotus::Utils::Hash

Examples:

require 'lotus/utils/hash'

hash = Lotus::Utils::Hash.new(
  'nil'        => nil,
  'false'      => false,
  'true'       => true,
  'symbol'     => :foo,
  'fixnum'     => 23,
  'bignum'     => 13289301283 ** 2,
  'float'      => 1.0,
  'complex'    => Complex(0.3),
  'bigdecimal' => BigDecimal.new('12.0001'),
  'rational'   => Rational(0.3),
  'string'     => 'foo bar',
  'hash'       => { a: 1, b: 'two', c: :three },
  'u_hash'     => Lotus::Utils::Hash.new({ a: 1, b: 'two', c: :three })
)

duped = hash.deep_dup

hash.class  # => Lotus::Utils::Hash
duped.class # => Lotus::Utils::Hash

hash.object_id  # => 70147385937100
duped.object_id # => 70147385950620

# unduplicated values
duped['nil']        # => nil
duped['false']      # => false
duped['true']       # => true
duped['symbol']     # => :foo
duped['fixnum']     # => 23
duped['bignum']     # => 176605528590345446089
duped['float']      # => 1.0
duped['complex']    # => (0.3+0i)
duped['bigdecimal'] # => #<BigDecimal:7f9ffe6e2fd0,'0.120001E2',18(18)>
duped['rational']   # => 5404319552844595/18014398509481984)

# it duplicates values
duped['string'].reverse!
duped['string'] # => "rab oof"
hash['string']  # => "foo bar"

# it deeply duplicates Hash, by preserving the class
duped['hash'].class # => Hash
duped['hash'].delete(:a)
hash['hash'][:a]    # => 1

duped['hash'][:b].upcase!
duped['hash'][:b] # => "TWO"
hash['hash'][:b]  # => "two"

# it deeply duplicates Lotus::Utils::Hash, by preserving the class
duped['u_hash'].class # => Lotus::Utils::Hash

Returns:

  • (Hash)

    a deep duplicated self

Since:

  • 0.3.1



162
163
164
165
166
# File 'lib/lotus/utils/hash.rb', line 162

def deep_dup
  Hash.new.tap do |result|
    @hash.each {|k, v| result[k] = Duplicable.dup(v, &DUPLICATE_LOGIC) }
  end
end

#delete(key) ⇒ Object?

Deletes the key-value pair and returns the value from hsh whose key is equal to key.

Parameters:

  • key (Object)

    the key to remove

Returns:

  • (Object, nil)

    the value hold by the given key, if present

See Also:

Since:

  • 0.3.0



189
190
191
# File 'lib/lotus/utils/hash.rb', line 189

def delete(key)
  @hash.delete(key)
end

#hashFixnum

Returns the hash of the internal @hash

Returns:

  • (Fixnum)

Since:

  • 0.3.0



261
262
263
# File 'lib/lotus/utils/hash.rb', line 261

def hash
  @hash.hash
end

#inspectString

Returns a string describing the internal @hash

Returns:

Since:

  • 0.3.0



270
271
272
# File 'lib/lotus/utils/hash.rb', line 270

def inspect
  @hash.inspect
end

#keysArray

Returns a new array populated with the keys from this hash

Returns:

  • (Array)

    the keys

See Also:

Since:

  • 0.3.0



175
176
177
# File 'lib/lotus/utils/hash.rb', line 175

def keys
  @hash.keys
end

#respond_to_missing?(m, include_private = false) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Override Ruby’s respond_to_missing? in order to support ::Hash interface

Returns:

Since:

  • 0.3.0



294
295
296
# File 'lib/lotus/utils/hash.rb', line 294

def respond_to_missing?(m, include_private=false)
  @hash.respond_to?(m, include_private)
end

#stringify!Hash

Convert in-place all the keys to Symbol instances, nested hashes are converted too.

Examples:

require 'lotus/utils/hash'

hash = Lotus::Utils::Hash.new a: 23, b: { c: ['x','y','z'] }
hash.stringify!

hash.keys    # => [:a, :b]
hash.inspect # => {"a"=>23, "b"=>{"c"=>["x", "y", "z"]}}

Returns:

Since:

  • 0.3.2



90
91
92
93
94
95
96
97
98
99
# File 'lib/lotus/utils/hash.rb', line 90

def stringify!
  keys.each do |k|
    v = delete(k)
    v = Hash.new(v).stringify! if v.is_a?(::Hash)

    self[k.to_s] = v
  end

  self
end

#symbolize!Hash

Convert in-place all the keys to Symbol instances, nested hashes are converted too.

Examples:

require 'lotus/utils/hash'

hash = Lotus::Utils::Hash.new 'a' => 23, 'b' => { 'c' => ['x','y','z'] }
hash.symbolize!

hash.keys    # => [:a, :b]
hash.inspect # => {:a=>23, :b=>{:c=>["x", "y", "z"]}}

Returns:

Since:

  • 0.1.0



65
66
67
68
69
70
71
72
73
74
# File 'lib/lotus/utils/hash.rb', line 65

def symbolize!
  keys.each do |k|
    v = delete(k)
    v = Hash.new(v).symbolize! if v.is_a?(::Hash)

    self[k.to_sym] = v
  end

  self
end

#to_a::Array

Converts into a nested array of [ key, value ] arrays.

Returns:

  • (::Array)

    the array

See Also:

Since:

  • 0.3.0



241
242
243
# File 'lib/lotus/utils/hash.rb', line 241

def to_a
  @hash.to_a
end

#to_h::Hash Also known as: to_hash

Returns a Ruby Hash as duplicated version of self

Returns:

  • (::Hash)

    the hash

See Also:

Since:

  • 0.3.0



225
226
227
228
229
230
# File 'lib/lotus/utils/hash.rb', line 225

def to_h
  @hash.each_with_object({}) do |(k, v), result|
    v = v.to_h if v.is_a?(self.class)
    result[k] = v
  end
end