Better Programming

Advice for programmers.

Member-only story

Why I Stopped Using Sorbet in All My Ruby Projects

Ashley Peacock
Better Programming
Published in
7 min readApr 12, 2023

--

Photo by Ross Sokolovski on Unsplash

For over five years, in a professional capacity, I’ve worked mostly on projects built using Ruby. Most of the systems I worked on used Ruby on Rails and varied in size from microservice to monolith.

For several of those years, I’d repeatedly get frustrated with Ruby’s dynamic nature, especially in the decade-old monolith. I’d end up debugging a problem, trying to understand what objects are being passed into a method, and finding myself having to jump through many classes to work it out or execute the code and use a debugger.

Neither of these is particularly enjoyable, so when Sorbet was open sourced by Sorbet in 2019, I couldn’t wait to give it a go. On the face of it, it was the answer to several frustrations I had working with Ruby. Suddenly, we could have types for method arguments, which would be statically checked by Sorbet.

However, after trialing it in several projects, my teams and I removed it entirely from our codebases. In this article, I’ll delve into why.

What is Sorbet?

For anyone not familiar, Sorbet is a type checker for Ruby. By default, Ruby has no type-checking, so you could write something like this:

def add_numbers(a, b)
a + b
end

add_numbers('1', 2)

And if you were to execute that, you’d get a lovely error, as you can’t add a string to an integer (unless you’re in JavaScript, and then you technically can):

`+': no implicit conversion of Integer into String (TypeError)

To get that error, though, you have to run the code. You could commit and deploy that code, and if your tests were particularly bad, it would make it to production. Even if your tests did catch it, running the code in a more complex codebase can be time-consuming, and failing early saves you a lot of time in the long run.

With Sorbet, however, you can define types for method signatures, like so:

sig {params(a: Integer, b: Integer).returns(Integer)}
def add_numbers(a, b)
a + b
end

add_numbers('1', 2)

--

--

Ashley Peacock
Ashley Peacock

Written by Ashley Peacock

Staff Software Engineer, Architect & Author

Responses (5)