The aesthetics of Ruby - Kernel#itself method
Recently, I’ve had quite a popular problem to solve: count the occurences of the given item in a collection. There are few ways to solve this problem - starting from using Enumerable#inject
or Enumerable#each_with_object
with an empty hash as an accumulator value and writing a code looking like this:
collection.each_with_object({}) { |item, accum| accum[item] = accum[item].to_i + 1 }
through a bit smarter way and taking advantage of the default hash value:
collection.each_with_object(Hash.new(0)) { |item, accum| accum[item] = accum[item] + 1 }
All these solutions look quite nice; however, there is one that looks particularly beautiful.
The Aesthetics of Ruby
An interesting way of solving this problem is by using Enumerable#group_by
- we can simply group elements by themselves and count the occurences of each item. Here is one way to implement it:
collection.group_by { |item| item }.map { |key, value| [key, value.count] }.to_h
However, it doesn’t look that great, especially for Ruby standard. We could do better. Ruby 2.4 adapted a very useful core extension from ActiveSupport: Hash#transform_values
. Thanks to this addition, we could rewrite that to the following code:
collection.group_by { |item| item }.transform_values(&:count)
Looks much better, but group_by { |item| item }
could still be improved. Is there anything in Ruby that could help us in such case?
It turns out there is! One of the additions in Ruby 2.2 was Kernel#itself
, which simply returns self. It might sound like an odd idea to introduce such method, but this is exactly something that we need:
collection.group_by(&:itself).transform_values(&:count)
This code looks just beautiful.
Wrapping up
Ruby code is known for being particularly pleasant to read and I’m still happy that after several years I still feel immense joy when I discover interesting little things like Kernel#itself
which add up to the overall aesthetics of the language.