Skip to content

Commit

Permalink
Merge remote-tracking branches 'origin/misc' and 'origin/typelike_mer…
Browse files Browse the repository at this point in the history
…ge' into HEAD
  • Loading branch information
notEthan committed Sep 5, 2019
2 parents c4e4b8d + 5458dfd commit ce56151
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 2 deletions.
42 changes: 41 additions & 1 deletion lib/jsi/typelike_modules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module Hashlike
SAFE_KEY_VALUE_METHODS = %w(< <= > >= any? assoc compact dig each_pair each_value fetch fetch_values has_value? invert key merge rassoc reject select to_h to_proc transform_values value? values values_at)
DESTRUCTIVE_METHODS = %w(clear delete delete_if keep_if reject! replace select! shift)
# these return a modified copy
safe_modified_copy_methods = %w(compact merge)
safe_modified_copy_methods = %w(compact)
# select and reject will return a modified copy but need the yielded block variable value from #[]
safe_kv_block_modified_copy_methods = %w(select reject)
SAFE_METHODS = SAFE_KEY_ONLY_METHODS | SAFE_KEY_VALUE_METHODS
Expand All @@ -105,6 +105,42 @@ module Hashlike
end
end

# the same as Hash#update
# @param other [#to_hash] the other hash to update this hash from
# @yield [key, oldval, newval] for entries with duplicate keys, the value of each duplicate key
# is determined by calling the block with the key, its value in hsh and its value in other_hash.
# @return self, updated with other
# @raise [TypeError] when `other` does not respond to #to_hash
def update(other, &block)
unless other.respond_to?(:to_hash)
raise(TypeError, "cannot update with argument that does not respond to #to_hash: #{other.pretty_inspect.chomp}")
end
self_respondingto_key = self.respond_to?(:key?) ? self : to_hash
other.to_hash.each_pair do |key, value|
if block_given? && self_respondingto_key.key?(key)
value = yield(key, self[key], value)
end
self[key] = value
end
self
end

alias_method :merge!, :update

# the same as Hash#merge
# @param other [#to_hash] the other hash to merge into this
# @yield [key, oldval, newval] for entries with duplicate keys, the value of each duplicate key
# is determined by calling the block with the key, its value in hsh and its value in other_hash.
# @return duplicate of this hash with the other hash merged in
# @raise [TypeError] when `other` does not respond to #to_hash
def merge(other, &block)
dup.update(other, &block)
end

def dup
Typelike.modified_copy(self, &:dup)
end

# @return [String] basically the same #inspect as Hash, but has the
# class name and, if responsive, self's #object_group_text
def inspect
Expand Down Expand Up @@ -186,6 +222,10 @@ module Arraylike
end
end

def dup
Typelike.modified_copy(self, &:dup)
end

# @return [String] basically the same #inspect as Array, but has the
# class name and, if responsive, self's #object_group_text
def inspect
Expand Down
2 changes: 1 addition & 1 deletion test/jsi_json_hashnode_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@
describe 'modified copy methods' do
# I'm going to rely on the #merge test above to test the modified copy functionality and just do basic
# tests of all the modified copy methods here
it('#merge') { assert_equal(JSI::JSON::Node.new_doc(node.content.to_hash), node.merge({})) }
it('#merge') { assert_equal(JSI::JSON::Node.new_doc(node.content), node.merge({})) }
it('#reject') { assert_equal(JSI::JSON::Node.new_doc({}), node.reject { true }) }
it('#select') { assert_equal(JSI::JSON::Node.new_doc({}), node.select { false }) }
# Hash#compact only available as of ruby 2.5.0
Expand Down

0 comments on commit ce56151

Please sign in to comment.