Skip to content

Commit e83f780

Browse files
committed
Fix Hash#to_h called with a block and pass key and value to the block as separate arguments
1 parent 954bfcf commit e83f780

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Compatibility:
3333
* Fix `Enumerable#reduce` to handle non-Symbol method name parameter (#2931, @andrykonchin).
3434
* Fix `RangeError` message to match CRuby for `Integer#chr` called with invalid codepoint argument (#2795, @andrykonchin).
3535
* Joni has been updated from 2.1.44 to 2.2.1 (@andrykonchin).
36+
* Fix `Hash#to_h` called with a block and pass key and value to the block as separate arguments (#3607, @andrykonchin).
3637

3738
Performance:
3839

spec/ruby/core/hash/to_h_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@
3737
{ a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v]}.should == { "a" => 1, "b" => 4 }
3838
end
3939

40+
it "passes to a block each pair's key and value as separate arguments" do
41+
ScratchPad.record []
42+
{ a: 1, b: 2 }.to_h { |k, v| ScratchPad << [k, v]; [k, v] }
43+
ScratchPad.recorded.sort.should == [[:a, 1], [:b, 2]]
44+
45+
ScratchPad.record []
46+
{ a: 1, b: 2 }.to_h { |*args| ScratchPad << args; [args[0], args[1]] }
47+
ScratchPad.recorded.sort.should == [[:a, 1], [:b, 2]]
48+
end
49+
4050
it "raises ArgumentError if block returns longer or shorter array" do
4151
-> do
4252
{ a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v, 1] }

src/main/ruby/truffleruby/core/hash.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,21 @@ def slice(*keys)
355355

356356
def to_h
357357
if block_given?
358-
super
358+
h = {}
359+
each do |k, v|
360+
elem = yield(k, v)
361+
unless elem.respond_to?(:to_ary)
362+
raise TypeError, "wrong element type #{Primitive.class(elem)} (expected array)"
363+
end
364+
365+
ary = elem.to_ary
366+
if ary.size != 2
367+
raise ArgumentError, "element has wrong array length (expected 2, was #{ary.size})"
368+
end
369+
370+
h[ary[0]] = ary[1]
371+
end
372+
h
359373
elsif instance_of? Hash
360374
self
361375
else

0 commit comments

Comments
 (0)