I’m trying to override a reader method on a Dry::Struct. I’ve got three approaches that work, but I’m not crazy about any of them. I was wondering if there’s an accepted best practice for doing this or if there’s just a better way to do this that I haven’t considered.
Here’s an example
class Thing < Dry::Struct
attribute :id, Types::String.enum("00", "02", "99")
end
I want the return value of Thing#name to always be 10 characters long and right-padded with 0s.
Approach #1
class Thing < Dry::Struct
attribute :id, Types::String.enum("00", "02", "99")
def id
@id.ljust(10, "0")
end
end
I don’t like this approach because it requires accessing the @id instance variable directly, which I consider to be an implementation detail of Dry::Struct and not part of its public interface.
Approach #2
class Thing < Dry::Struct
attribute :id, Types::String.enum("00", "02", "99")
alias orig_id id
def id
orig_id.ljust(10, "0")
end
end
I think this approach is better than #1 but it’s kind of ugly, IMO.
Approach #3
module ThingOverrides
def id
super.ljust(10, "0")
end
end
class Thing < Dry::Struct
prepend ThingOverrides
attribute :id, Types::String.enum("00", "02", "99")
end
This approach is kind of elegant, but introducing a new module every time you want to override a method seems like overkill.
Any thoughts?