Any way to make initializer raise on unknown options?
ivan-kolmychek opened this issue · 2 comments
If you define regular ruby class with keyword arguments, it will raise if you provide it unknown options:
class Whatever
def initialize(a:, b:)
end
end
irb(main):006:0> Whatever.new(a: 1, b: 2, c: 3)
Traceback (most recent call last):
4: from /usr/bin/irb:11:in `<main>'
3: from (irb):6
2: from (irb):6:in `new'
1: from (irb):2:in `initialize'
ArgumentError (unknown keyword: c)
Dry-initializer does not.
Is there any way to make dry-initializer raise on unknown options?
Hi @ivan-kolmychek !
Well, technically this could be implemented (for example, we could configure the initializer itself like extend Dry::Initializer[:intolerant]
, but for some additional cost at a runtime.
The reason is that under the hood the gem uses the [all-tolerant signature][https://github.com/dry-rb/dry-initializer/blob/master/lib/dry/initializer/builders/signature.rb#L9]. That's why you'll have to add the check [somewhere during the instantiation][https://github.com/dry-rb/dry-initializer/blob/master/lib/dry/initializer/builders/initializer.rb#L22-L30].
Of course, this shouldn't touch the performance for the default config, still I don't think it worth it.
In case you know the options in advance, you could just overload the initializer in your class (for about the free):
def initialize(a: nil, b: nil)
super
end
Otherwise, you could use class-level settings to check what options you've defined
def initialize(**data)
unknown_keys = self.class.dry_initializer.options.map(&:source) - data.keys
raise KeyError if unknown_keys.any?
super
end
The last possibility is the same code you'd need to implement for Dry::Initializer[:intolerant]
Thanks. Well, we have something like second option in our "homebrew" solution and dry-initializer still saves us a lot of code, so that may be an all right option indeed.
And in case we'll decide to PR adding it, you already pointed out know where to look. :)