dry-rb/dry-initializer

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. :)