self.each do |key, value|
new_hash[key] = hash[key] ? prc.call(key, value, hash[key]) : value
end
hash.each do |key, value|
new_hash[key] = value if new_hash[key].nil?
end
new_hash
end
end
end
I got error:Failures:
Hash#my_merge yields each element to the block
Failure/Error: expect { |b| test_hash_1.my_merge(test_hash_2, &b)}.to yield_successive_args([:b, 2, 3])
expected given block to yield successively with arguments, but yielded with unexpected arguments
expected: [[:b, 2, 3]]
got: [[:b, 2, 3], [:c, nil, 4]]
./spec/exercises_spec.rb:190:in `block (2 levels) in <top (required)>’
Hash#my_merge returns a hash with the correct key-value pairs
Failure/Error: expect(test_hash_1.my_merge(test_hash_2) { |key, oldval, newval| newval - oldval }).to eq({a: -5, b: 8, c: 3})
I just ran your code and it passes all the specs. Here’s the code I ran (with improved formatting):
class Hash
def my_merge(hash, &prc)
prc ||= Proc.new { |k, oldval, newval| newval }
new_hash = {}
self.each do |key, value|
new_hash[key] = hash[key] ? prc.call(key, value, hash[key]) : value
end
hash.each do |key, value|
new_hash[key] = value if new_hash[key].nil?
end
new_hash
end
end
I think we’re talking past each other. I just ran the code that you provided. Where did you get the code from?
The ? is called a ternary operator. The line new_hash[key] = hash[key] ? prc.call(key, value, hash[key]) : value works as follows. If hash[key] is truthy (not nil), then new_hash[key] gets assigned prc.call(key, value, hash[key]). Otherwise it gets assigned value.
The issue with your code is that you’re calling the block even if new_hash[k2] is not defined, i.e. if it’s nil. Try to think of a way to execute the line new_hash[k2] = prc.call(k2,new_hash[k2],v2) only if new_hash[k2] is defined.
Thank you so much!
I just added a conditional statement under my else, and it worked:
if new_hash[k2]
new_hash[k2] = prc.call(k2,new_hash[k2],v2)
else
new_hash[k2] = v2