The making of Ruby Changes: A boring advent
A diary of preparing Ruby 3.3's annotated changelog throughout the December of 2023.
I have been writing in Ruby for almost 20 years; my first version was Ruby 1.6. I was always curious to observe how the language evolves, always trying to see what the changes might help me understand about my own usage of it, the community, and the ways of thinking in code. For me, understanding how it changes helped me to understand how it is.
The changelog
Five years ago, I started the Ruby Changes project, whose mission was to provide the context of the new and adjusted features: why they were invented, what the design space was, and how exactly it behaves. This activity was useful for my own deeper understanding, and judging by the community reaction, many felt the same.
It also turned out that by working on the changelog, I was able to give back to Ruby, discovering small inconsistencies or lacking documentation about the change I was trying to describe. I told more about this in a “big picture of work on the changelog and participating in the Ruby evolution” series of articles a couple of years ago (“What you can learn by merely writing a programming language changelog”, “Following the programming language evolution, and taking it personally”, “Programming language evolution: with all that, we are still flying”).
Since then, every year, I covered a freshly released version and, sometimes, went deeper, like covering versions 2.4 and 2.5 that were released before the “Ruby Changes” project started or creating a “Ruby Evolution” bird-eye view of the (by now) ten-year span of changes since 20131.
The advent
This year, I decided on the experiment of “advent-style” work on changelog: the time-boxed everyday work, with parallel writing of the diary, explaining how the work is done and how I think about things related to it. At the very least, the idea helped to keep discipline: last year I was two months late, which is bad not only because by the time of the changelog publishing, those interested had already looked into everything themselves but also because the discovery of small inconsistencies in docs or behavior was made only after the release.
It was my hope that I could make “the diary of working on changelog” an interesting journey for the outside reader.
Well, now that everything is done and the changelog is published on time, I have mixed feelings about the experiment.
The accidental journey just took some 55-65 working hours (24 days, with at least 2 hours on most working days, and usually more on weekends), during which I did:
the changelog itself;
a few tickets in the bug tracker, some clarifying, some to be fixed before the release, some uncovering slight old bugs in the dark corners (there was also at least one problem that I’ve missed despite adding the feature to the changelog—given, the corresponding feature were merged just a few hours before the final release);
a few documentation improvements;
a small PR to the standard library (unfortunately, not merged before the release—as well as a relatively big core feature I got accepted in principle before my mobilization but didn’t have time to finalize properly);
a huge backlog of things that can be fixed in the old documentation for better understanding and consistency, and of ideas/proposals about the edge cases of the language behavior;
…and, well, the diary.
The outcome
So, what about the diary?
I had an experiment with the “advent” of code reading/rewriting two years ago; during that work, writing the diary was the activity that definitely helped. It documented the adventure and my thoughts/ideas on software writing and is, in fact, its primary outcome (while the rewritten code is rather supplementary material). It also helped to organize thoughts and was a welcome switch of activities after digging into the code and debugging.
The “advent of changelog” is a more specific product: I needed to write a text about (mostly) writing a text; there wasn’t much “activity type” switching, and also I constantly needed to decide what to include in the diary, so it would be (hopefully) interesting to read, without just putting there “spoilers” of feature descriptions I just wrote.
In hindsight, all of that is not that exciting to do—and, most probably, not that exciting to read about! It also didn’t help that this year’s version has much more internal implementation changes (the main sections of the official release note are all dedicated to that) than language syntax/API changes, which is what all of my changelog is about.
So the whole work seems a bit “out of focus” this year, as if everything I am covering is just notes on the margins of the “main changes of this version.” Still, I maintain that observing how the language changes might be of interest—even if this year’s changes aren’t that big.
The part of the diary that concerns fixing the documentation wording and rendering might look patronizing, or else expose the community in a bad light, or emphasize me as an extremely valuable Keeper of Order. I meant nothing like that. There are just a few things I wanted to communicate with this diary:
how the intention to see structures in everything can be tamed and used to do “the boring work” of just describing other people's work;
what amount of small things can be uncovered and questioned by just creating such a structure;
how many small things need to be fixed every day of the language’s life—even when all the big things are in place, thoroughly discussed, and well-tested.
This everyday work, which I take on myself only once a year, is just a fraction of what more experienced and involved core team members do all around the clock. Ruby’s development process is highly informal, and somebody needs to handle “the boring stuff.” And usually, somebody does. I just did a small bit.
The diary
Here is a diary of this “boring work”—hopefully, not that boring still, with my “chaotic good” style of handling tasks and thinking about them (which I sometimes feel matches the language’s development style in general).
There are 24 entries; each day is a link. The first half of them were already linked in the previous posts, but I am putting it all here for convenience:
Day 1, where I explain my usual process and start by looking into this year’s
NEWS.md
file in Ruby repo. From first sight, it looks like this year’s release has very few changes, and even less so to analyze and describe in detail, so it might not be the best year to showcase “what it takes.”” (Spoiler alert: this was a false feeling!)Day 2, where I go into more details about converting terse official
NEWS.md
into my wordy changelog sections, and a lot of uncertainties to think of in the process.Day 3, where I do an initial pass through all the new/changed feature docs and uncover many small enhancement possibilities to put in my December TODO.
Day 4, where I start to look into the features that I need to understand better before explaining them, and, in particular,
Module#set_temporary_name
.Day 5, where I look into a few more new features: a new
WeakKeyMap
class, andThread::Queue#freeze
method, and demonstrate how I reflect upon uncertainties in my own understanding and possible documentation problems I’d like to fix.Day 6 & day 7, where I am diving head-first into enhancing docs for a new class
ObjectSpace::WeakKeyMap
and its older cousinObjectSpace::WeakMap
, and end with submitting a PR to Ruby core and finally writing some drafty texts for the changelog.Day 8, where new features are landing in Ruby’s
NEWS.md
, while I am working on a PR to fix small documentation problems in Ruby’s docs.Day 9, where I prepare one more documentation-fixing PR and notice some changes are still missing from
NEWS.md
.Day 10, where I finally sumbit myself into writing a big part of the changelog, but also discover some small new inconsistencies to report, possible language improvements to pursue, and philosophical problems to ponder upon.
Day 11, where I try to proceed, but it entangled into some lack of understanding, old surprising behaviors, and historical discussions (and also meet my younger self accidentally).
Day 12, where I recompile Ruby and investigate the new (if not yet fully materialized) possibilities that would be opened with the introduction of
it
anonymous block argument next year.Day 13, where I am almost done with the first, quick-and-rough part of the changelog.
Day 14, where I am summarizing what was done and writing this blog post.
Day 15, where I plan for the rest of the work and estimate the time it takes.
Day 16, where I get a first rendering of the changelog draft and explain my approach to structuring it into bigger sections (while also feeling uneasy about imposing the structure I invented).
Day 17, where I add the changes related to the standard library contents, and find a few more inconsistencies to poke and documentation problems to fix.
Day 18 and day 19, where I go over all of the small places in the changelog that created questions, needed improvement, led to unpleasant discoveries about documentation rendering—but in general, the changelog is kind of done by now.
Day 20, where I am taking on adjusting the official
NEWS.md
with the features that were added through the year but haven’t been described there—and dutifully add them to the changelog, too.Day 21, where I adjust the old changelog with forward links of “how it became in new versions.”
Day 22, where I update the Ruby Evolution page (and explain how and why it is structured).
Day 23, where I add the
Set
’s changes to the changelog and explain why they were missing inNEWS.md
Day 24-25, where I wrap everything up, link to the important standard library changes, Ruby 3.3 is released, the changelog is published… and one last moment change is, of course, forgotten, and then merged right into the
master
, because that’s how everything is done!
So, yeah… That’s that.
Subscribe to my Substack, or follow me on Twitter.
A weekly postcard from Ukraine
Please read this too. This is your weekly reminder that I am a living person from Ukraine, and a bit of useful related information.
One news item. “They brought him home and shot him”: occupants killed a schoolboy in front of his family in Kherson region
One fundraiser. This Christmas, as ever, the “Hospitalliers” medical battalion can use some funds to save lives!
One plea. Please read and spread info about Azovstal and Mariupol defenders who are still in captivity.
I know I am repeating this information from time to time, but I intend to share this article with a broader audience than just the Ruby community, so I decided to put down some context.