Ruby refinements and the sorbet type checker

Ruby refinements and the sorbet type checker

On the latest project I have been working on, we decided to implement the sorbet type system from day 1. And recently had to some code similar to the below: -

class MyClass
  extend T::Sig

  sig { returns(T::Hash[String, Enumerable]) }
  def personal_emails
    @personal_emails ||= communications.fetch(:email) { [] }
                                       .index_by(&:use_code)
                                       .reject { |k, _v| k.nil? }
  end

  # Simplified output from remote data store
  sig { returns(T::Hash[String, T::Array[Enumerable]]) }
  def communications
    {
      email:   [
        { name: 'Foo', use_code: 'personal' },
        { name: 'Bar', use_code: 'business' },
        { name: 'Bar', use_code: nil }
      ],
      telephone: [
        { name: 'Baz', use_code: 'personal' }
      ]
    }
  end
end

Now, this is fine for a single method, but as we continue and we start mapping more of the fields, we start to get more and more duplication.

read more