A couple nights ago I was overcome with the urge to publish a Ruby gem. I have been writing Ruby for over 5 years and realized that it was time to give Ruby development outside of Stripe's Ruby infra a shot.
                The package is
                eclair
                which I've wanted to build on and off for about three years now.
                It's worth its own article and context, so that's all I'll say
                about the gem itself here.
              
I wanted to put a strong foot forward when publishing the gem. I do a lot of advocacy for writing high-quality Ruby code, mostly internal to Stripe, but also in public. Check out Ruby style guide and Effective Sorbet for most of the advice.
However, I haven't shared a whole Ruby library in public before. While I didn't expect to do a perfect job with the new stuff, I did want to get some things right.
Requirements:
strict typing as the minimum.
                rubyfmt.Plus the stuff I would do in any design:
                    I learned much more about the Ruby language's built-in
                    tooling. It's cool to see ruby,
                    irb, bundle, and
                    gem all coming as a unit. Never really knew
                    they flocked together. Getting Ruby to a newer version got
                    all these things to a newer version too.
                  
                    I'm a big fan of Clojure. In that ecosystem the mantra is
                    everything is data. You often write configuration files as
                    Clojure data structures. It was cool to see Ruby doing a
                    similar thing, even if it forgot the data part.
                    Gemfile, Gemspec,
                    Rakefile are all Ruby code. I've definitely
                    touched Stripe Gemfiles before but working with the RubyGem
                    registry made it so much clearer how everything was fitting
                    together.
                  
The Sorbet VSCode extension can be slow at Stripe scale. On a few hundred billion lines less of Ruby it was amazing.
                    The minitest style of tests were nice. Having
                    really only written RSpec-like tests,
                    minitest feels a lot less magical and much
                    smaller. Definitely reminded me of Go tests.
                  
I wanted to follow Effective Sorbet precisely but there was one thing that I could not do because I felt it was not appropriate for an open-source project.
                Despite recommending them heavily, I didn't use
                T::Struct. I had used
                T::Struct initially but switched to plain old Ruby
                objects (POROs).
              
                The reasoning: too many methods and too many
                bad methods, e.g. with, from_hash, etc. I can't
                feel comfortable shipping a gem with that much baggage of
                unexpected behavior.
              
Stripes write friction logs. A friction log is basically a stream of conscious document that details everything and anything that went wrong or felt off about doing something. As a platform team lead, I get friction logs from folks across the company all the time. Those logs feed into what we choose to prioritize. It's a good system.
Here's a distillation of my frictions:
By far I wasted the most time trying to get Ruby set up on my Macbook. Stripe-issued laptops solve this problem so I hadn't felt the pain before.
Apple ships an old version of Ruby (~v2.6) but all the tooling I worked with expected Ruby 3.0. In retrospect, had I got the Ruby version issue fixed earlier in the process so many things would have been smoother.
                I felt this pain most when setting up Sorbet, in particular
                initializing my project with
                Tapioca. The
                exception thrown running
                bundle exec tapioca init wasn't super helpful but
                luckily enough to search me up a
                lead on how to fix it.
              
                Once I eventually got rbenv setup and working, and
                had rebooted everything to use it instead of the Mac-default
                Ruby version things got better.
              
In terms of wall-clock time spent, RubyGems caused me the greatest time loss. RubyGems is great but the search page results were a bit all too easy to misread. When I started my gem-ing, the first thing I did was see if the name "eclair" was available. I got so excited because I saw it was.
                It was only after a long night of working on the gem itself that
                I finally went to publish my gem and it turned out
                eclair was not available. The gem had been recently
                "yanked," meaning taken down by its author. The gem
                was unused but I wouldn't be able to claim it for 3 months.
              
Betrayal, the worst of all.
Luckily only a little more than a day later after reaching out to the current gem owner, they graciously transferred the gem over to me. Thanks again, Cyrus!
rubyfmt
              
                The Ruby formatter rubyfmt doesn't seem to
                integrate with the
                Ruby LSP extension. It probably works with the old "Ruby" extension but
                VSCode steers people away from downloading that one.
              
This isn't a big deal, I just didn't manage to get format-on-save working.
                Overall publishing a Ruby gem was a pleasant experience. I
                learned a good amount from it and it was nice learning how to
                set up Sorbet, rubyfmt, and other things I'd only
                previously used because someone else installed them for me.
                Thanks for reading!