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(
:application_name,
:application_version,
:proxy_url,
:open_timeout_sec,
:read_timeout_sec,
:send_timeout_sec,
:log_http_requests,
:transparent_gzip_decompression)
# ...
class ClientOptions
# ...
def self.default
@options ||= ClientOptions.new
end
end
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.
Psst - if this was useful, consider sponsoring a coffee (or sushi) for me πββοΈ: