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.