This post describes what I think is a major flaw in Ruby’s built-in Struct class, and proposes a workaround.

Image for post
Image for post
Documentation for Ruby’s built-in Struct class

This blog post does a good job of explaining the benefits of using Struct for value objects.

Here’s my gripe with Struct: Although fields in a Struct are named (unlike an array, or Python’s tuple), named/keyword arguments aren’t allowed when instantiating a Struct object.

This defeats the purpose of having named fields in the first place! The benefit of having named fields is that they attach meaning to your data. Birthday.new(day: 5, month: 7) is undoubtedly more clear than Birthday.new(5, 7).

To work around this, I’ve been adding the following class to all projects where I use Struct:

This is also available as a gem, if you’d prefer to not repeat yourself.


While improving a build script by parallelising actions, I realised that Ruby’s puts is not atomic.

Effects of the race condition in action

Looks like puts is calling the underlying write function twice - Once to actually print the variable given to it, and once again to print the newline character. This leads to a race condition in puts, as observed above.

I confirmed this by taking a look at the source code for puts in Rubinius and MRI.

Image for post
Image for post

About

Paul Kuruvilla

Practical and fact-minded individual, whose reliability cannot be doubted.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store