Custom initializer when subclassing Dry::Struct

I’ve been using dry-struct in most of my Ruby projects. This time around, I had to do something a little bit unusual: I have a subclass that requires less information than its parent. So here is how I wrote my custom initializer when subclassing Dry::Struct.

The Problem

The solution seems simple: the subclass should simply not send part of the information to its base constructor. But Dry::Struct was built in a way that we can’t do that as easily. The first thing I tried was the following:

Line 21 works correctly, but this is not what I wanted to achieve. I wanted to not have to specify X when creating the object, like the line 22. When doing so, I got greeted with a: in `block in resolve_missing_keys': :X is missing in Hash input (Dry::Types::MissingKeyError).

After investigating the callstack, I figured that the validation was not done in the initializer, but in the class’s new function.

The Solution

Armed with the information that the validation is done in the new function, I tried something else. The following is the version I ended up with:

The magic is on line 15: instead of defining an initializer, I overload the new function of my class. This allows me the same control as an initializer but does this before Dry::Struct validations.

Now, is this the best solution … probably not. But following the documentation, I could not find any other ways to do it.

Tagged . Bookmark the permalink.

Leave a Reply