lib/lotus/utils/hash.rb in lotus-utils-0.3.0 vs lib/lotus/utils/hash.rb in lotus-utils-0.3.1
- old
+ new
@@ -55,10 +55,77 @@
end
self
end
+ # Return a deep copy of the current Lotus::Utils::Hash
+ #
+ # @return [Hash] a deep duplicated self
+ #
+ # @since x.x.x
+ #
+ # @example
+ # 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
+ def deep_dup
+ Hash.new.tap do |result|
+ @hash.each {|k, v| result[k] = duplicate(v) }
+ end
+ end
+
# Returns a new array populated with the keys from this hash
#
# @return [Array] the keys
#
# @since 0.3.0
@@ -179,9 +246,25 @@
#
# @api private
# @since 0.3.0
def respond_to_missing?(m, include_private=false)
@hash.respond_to?(m, include_private)
+ end
+
+ private
+ # @api private
+ # @since x.x.x
+ def duplicate(value)
+ case value
+ when NilClass, FalseClass, TrueClass, Symbol, Numeric
+ value
+ when Hash
+ value.deep_dup
+ when ::Hash
+ Hash.new(value).deep_dup.to_h
+ else
+ value.dup
+ end
end
end
end
end