TIL: Extending a Ruby Struct

November 07, 2021

Last week I had a head-scratching moment looking at the following code (from the google-api-ruby-client):

ClientOptions = Struct.new(

# ...

class ClientOptions
    # ...
    def self.default
    @options ||= ClientOptions.new

My initial confusion stemmed from the assumption that the first ClientOptions declaration returned a regular object. A helpful colleague explained to me that Struct.new actually returns a subclass of Struct. That meant the second class ClientOptions declaration was actually re-opening the class to add a method, not to declare a new class.

Why would one want to do this? Well, one would get all the methods of a regular Struct (e.g. accessors, iterators) for free at the cost of the inheritance hierarchy. This could be useful for ValueObjects.


Written by Nick who is a indie-hacker wannabe, living in sunny Singapore. Twitter | GitHub