How learning Rust changed my Ruby Workflow

 
Rust is represented by a crab on a beach Photo by Alexsandro Rosa de Mello from Pexels


For the last few months, I’ve been working semi-full-time on my first Rust project. After the first painful weeks of struggling against The Compiler, I feel I’m now spoiled by Rust development experience. In this blog post, I’ll describe improvements to my Ruby workflow that originate from what I’ve seen in the Rust ecosystem.

“Mom, can we have a Ruby compiler?”

Despite similar syntax, Rust and Ruby are vastly different. Compiled vs. interpreted, rigid type system vs. “If it quacks…“.

The initial learning curve is relatively steep, with the simplest implementations requiring type-related annotations. This “syntax overhead” might initially seem pointless for someone with a Ruby background. It clicked for me when I realized that compiler feedback works similarly to TDD.

I’m using a standard Rust-analyzer extension for VS-code. On each file save, I receive inline and instant feedback on where my code is buggy. Without leaving my IDE to run a test. Also, without having to write any test at all! I’ve worked comercially with other compiled languages (Obj-C and Swift) but never experienced a similar positive feedback loop.

There’s research on TDD techniques improving focus and flow state. From my limited experience with Rust, you can expect similar results without the overhead of maintaining an extensive test suite. Of course, the type-system won’t catch all the bugs. But, I’ve found myself writing limited tests only for logic bottlenecks.

Ruby compiler at home

I’ve kind of became addicted to this instant feedback. My poor man’s workaround to get similarish development experience in Ruby is the recently released devloop gem. It’s a Rspec test runner that focuses on speed and continuous feedback. I’ve hacked together fswatch and git diff output to run only recently modified specs. As a result, on each file save you’ll get test feedback within around a ~second.

Another interesting use case is that you can instantly run a spec by modifying its description. Before, I used the IDE extension shortcut to copy file path with line number and run rspec, but it’s cumbersome to do manually.

devloop gem running selected Rspec tests

~250ms to execute a bunch of specs with Spring enabled


I’m using devloop with an inline VS code terminal that I toggle using a shortcut. It means that I can quickly investigate output without losing focus.

I may have overlooked something but could not find a similar tool in the Ruby ecosystem. There’s no longer maintained guard-rspec. TLDR has a philosophy similar to devloop, but requires rewriting test suite to its custom API. retest is a comprehensive test runner, but it lacks the ability to run only subset of tests from a modified file.

devloop gem is in a very early stage of development, so feedback and PRs are welcome.

Tabs vs. spaces

Another thing that surprised me in the Rust ecosystem is that there seems to be a consensus on code formatting and linting. Just cargo ftm, and your code is now beautiful. In my Ruby career, I’ve been through too many holy wars for '' vs "", so it’s mindblowing!

I’ve seen Ruby code reviews turn into nitpicks on code formatting issues. They sometimes escalated into a battle of egos on why MY PREFERENCES are more better than YOUR PREFERENCES. Also, code formatting imperfections are the easiest to spot, so they often overshadow logic-related issues. There’s limited time and mental power a dev can allocate to the code review process. So, funneling it towards topics that matter could be beneficial.

I’ve started using rufo formatter, but there’s also standard and rubyfmt. I love that they are not configurable because it does not leave a place for endless code-style discussions and tweaks:

cat .rubocop.yml | wc -l
     277
My legacy.


Neither suits my “code formatting tastes” perfectly, but I don’t care. My mind CPU cycles are better spent elsewhere. It now seems ridiculous that for the last ten+ years, I was formatting my Ruby code manually… (╯°□°)╯︵ ┻━┻

I think that any Ruby project that adopts a nonconfigurable, “format on save” policy will instantly improve devs’ productivity and the quality of the code reviews.

BTW if you plan to do it, don’t forget about .git-blame-ignore-revs as described in this post.

Summary

I hope you’ll find some of these tips helpful. I’ll be posting more Ruby/Rust content. So don’t forget to like and subscribe.

And give Rust a try, it’s awesome!



Back to index