Skip to content

Commit 41d4eb1

Browse files
committed
[GR-40333] Ruby 3.1 Add optional Hash argument to Enumerable#tally
PullRequest: truffleruby/3684
2 parents 0122523 + c1a30c2 commit 41d4eb1

File tree

4 files changed

+26
-13
lines changed

4 files changed

+26
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ Compatibility:
8686
* Add `freeze` keyword argument to `Marshal.load` (#2733, @andrykonchin).
8787
* Add `Integer.try_convert` (#2733, @moste00, @eregon).
8888
* Support optional `:in` keyword argument for `Time.now` and `Time.new` (#2733, @andrykonchin).
89+
* Add optional `Hash` argument to `Enumerable#tally` (#2733, @andrykonchin).
8990

9091
Performance:
9192

spec/ruby/core/enumerable/tally_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,26 @@
4949
enum.tally(hash).should equal(hash)
5050
end
5151

52+
it "calls #to_hash to convert argument to Hash implicitly if passed not a Hash" do
53+
enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
54+
object = Object.new
55+
def object.to_hash; { 'foo' => 1 }; end
56+
enum.tally(object).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1}
57+
end
58+
5259
it "raises a FrozenError and does not update the given hash when the hash is frozen" do
5360
enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
5461
hash = { 'foo' => 1 }.freeze
5562
-> { enum.tally(hash) }.should raise_error(FrozenError)
5663
hash.should == { 'foo' => 1 }
5764
end
5865

66+
it "raises a FrozenError even if enumerable is empty" do
67+
enum = EnumerableSpecs::Numerous.new()
68+
hash = { 'foo' => 1 }.freeze
69+
-> { enum.tally(hash) }.should raise_error(FrozenError)
70+
end
71+
5972
it "does not call given block" do
6073
enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
6174
enum.tally({ 'foo' => 1 }) { |v| ScratchPad << v }

spec/tags/core/enumerable/tally_tags.txt

Lines changed: 0 additions & 7 deletions
This file was deleted.

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

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,23 @@ def slice_when(&block)
284284
end
285285
end
286286

287-
def tally
288-
h = {}
287+
def tally(hash = undefined)
288+
if Primitive.undefined?(hash)
289+
hash = {}
290+
else
291+
hash = Truffle::Type.rb_convert_type(hash, Hash, :to_hash)
292+
Primitive.check_frozen(hash)
293+
end
294+
289295
each do
290296
e = Primitive.single_block_arg
291-
if h.key?(e)
292-
h[e] += 1
297+
if hash.key?(e)
298+
hash[e] += 1
293299
else
294-
h[e] = 1
300+
hash[e] = 1
295301
end
296302
end
297-
h
303+
hash
298304
end
299305

300306
def to_a(*args, **kwargs)

0 commit comments

Comments
 (0)