Ruby 3.1 accumulates Enumerable#tally results

Ashik Salman

Ashik Salman

April 20, 2021

This blog is part of our  Ruby 3.1 series.

We already know the Enumerable#tally method is used to count the occurrences of each element in an Enumerable collection. The #tally method was introduced in ruby 2.7.0. Please check our blog for more details on it.

Ruby 3.1 introduces an optional hash argument for the Enumerable#tally method to count. If a hash is given, the total number of occurrences of each element is added to the hash values and the final hash is returned.

Ruby 2.7.0+

1=> letters = ["a", "b", "c", "a", "d", "c", "a", "c", "a"]
2=> result = letters.tally
3=> {"a"=>4, "b"=>1, "c"=>3, "d"=>1}

Before Ruby 3.1

1=> new_letters = ["a", "b", "c", "a", "c", "a"]
2=> new_letters.tally(result)
3=> ArgumentError (wrong number of arguments (given 1, expected 0))

After Ruby 3.1

1=> new_letters = ["a", "b", "c", "a", "c", "a"]
2=> new_letters.tally(result)
3=> {"a"=>7, "b"=>2, "c"=>5, "d"=>1}

The value corresponding to each element in the hash must be an integer. Otherwise, the method raises TypeError on execution.

If the default value is defined for the given hash, it will be ignored and the count of occurrences will be added in the returned hash.

1=> letters = ["a", "b", "c", "a"]
2=> letters.tally(Hash.new(10))
3=> {"a"=>2, "b"=>1, "c"=>1}

Here's the relevant pull request and feature discussion for this change.

If this blog was helpful, check out our full blog archive.

Stay up to date with our blogs.

Subscribe to receive email notifications for new blog posts.