module Hanami module Utils # Safe dup logic # # @since 0.6.0 module Duplicable # Duplicates the given value. # # It accepts a block to customize the logic. # # The following types aren't duped: # # * NilClass # * FalseClass # * TrueClass # * Symbol # * Numeric # # All the other types are duped via #dup # # @param value [Object] the value to duplicate # @param blk [Proc] the optional block to customize the logic # # @return [Object] the duped value # # @since 0.6.0 # # @example Basic Usage With Types That Can't Be Duped # require 'hanami/utils/duplicable' # # object = 23 # puts object.object_id # => 47 # # result = Hanami::Utils::Duplicable.dup(object) # # puts result # => 23 # puts result.object_id # => 47 - Same object, because numbers can't be duped # # @example Basic Usage With Types That Can Be Duped # require 'hanami/utils/duplicable' # # object = "hello" # puts object.object_id # => 70172661782360 # # result = Hanami::Utils::Duplicable.dup(object) # # puts result # => "hello" # puts result.object_id # => 70172671467020 - Different object # # @example Custom Logic # require 'hanami/utils/duplicable' # require 'hanami/utils/hash' # # hash = { a: 1 } # puts hash.object_id # => 70207105061680 # # result = Hanami::Utils::Duplicable.dup(hash) do |value| # case value # when Hanami::Utils::Hash # value.deep_dup # when ::Hash # Hanami::Utils::Hash.new(value).deep_dup.to_h # end # end # # puts result # => "{:a=>1}" # puts result.object_id # => 70207105185500 - Different object def self.dup(value, &blk) case value when NilClass, FalseClass, TrueClass, Symbol, Numeric value when v = blk&.call(value) v else value.dup end end end end end