Structs and attributes: wrapping a Struct in a class
TL;DR wrapped a Stuct in a class today and it felt good to get object attributes, but I feel like I violated a OOP principle.
Background and Statement of Problem
I was working on a Ruby API wrapping the Chef Automate REST API, Automate
Soup. To make the requests I used
the net/http
, which turns the response bodies into Ruby Hash objects.
Interacting with Hash’s in Ruby is pivotal, but what happens when you would like
to add some state around that Hash while keeping the dynamic attributes?
The Solution
The solution I propose is to provide a contract is to introduce a class. The
class will encapsulate the attributes we know exist as well as add some state
around those attributes is to introduce a class. To maintain the ability to
reach attributes on the Hash this solution will use an underlying OpenStruct
and delegate method_missing
to the OpenStruct
.
This solution was chosen so that we can maintain the attribute accessors with little to no code overhead. However, my feeling is that there are unintended consequences with this solution. Here is a code snippet of how this was accomplished, trimmed for your viewing pleasure. To see the full code checkout the Automate Soup repo.
Alternatives
Another alternative I though about was instead of an OpenStruct
to use a
Hash
, delegate method_missing
to access the attribute on the hash, and
override []
to also fetch from the underlying Hash
. My immediate thoughts
would be that this would cut down on the amount of memory used as Hashes are
relatively cheap in Ruby.
Call To Action
Would love to hear feedback/better ways/how you solve this problem! You can reach me on twitter at @skylerto.