Write options or configurations without worry of typos and the need to remember all the keys.
Have you ever used ruby options like this:
# this example is for rails
d = DateTime.now
e = d.change(hour: 1, minute: 5)
You think everything works fine, but it's not.
There is no key :minute
in options used by #change
.
If only the source of the DateTime#change
method starts like this:
# this class can be defined on its own file, just remember to require it
class ChangeOptions < SmartKv
optional :nsec, :usec, :year, :month, :day, :hour, :min, :sec, :offset, :start
end
class DateTime
...
def change(options)
options = ChangeOptions.check(options)
...
end
end
So, when you do this d.change(hour: 1, minute: 5)
, it will yell:
KeyError: unrecognized key: :minute in ChangeOptions
That's better. But, how do you know all the right options?
Type: ChangeOptions.keys
class Config < SmartKv
required :some_key, :second_key
optional :an_option
end
Config.check({some_key: "val"})
This will complain that you're not using the :second key
.
If you add another key that is not recognized, it will complain too.
If there is a key that you don't always use but want it to be recognized, mark it as optional
.
class ChildConfig < Config
required :first_key
end
ChildConfig.check({first_key: "val", second_key: "val 2"})
This will also complain that you're not using the :some_key
.
Whatever given as input is callable directly.
c = Config.check({some_key: "val", second_key: "val 2"})
c[:some_key]
c2 = Config.check(OpenStruct.new({some_key: "val", second_key: "val 2"}))
c2.second_key
You can change the callable object to any class that accepts hash as input of its new class method.
class Convertable < SmartKv
required :abcd
callable_as OpenStruct
end
c = Convertable.check({abcd: 123})
c.abcd #=> 123
When you make typo when writing a key of an options, you can get suggestions.
class LanguageScore < SmartKv
required :ruby
optional :rust, :kotlin, :elixir
end
LanguageScore.check({ruby: 100, korting: 90})
# SmartKv::KeyError: unrecognized key: :korting in LanguageScore.
# Did you mean? :kotlin
You can choose not to use it for options or configs. Maybe for strict request body keys?
class PostBody < SmartKv
required :app_key, :secret_key
end
.
.
request.set_form_data(PostBody.check({app_key: "abc", secret_key: "def"}))
One close alternative that is quite similar in objective is probably dry-schema.
Add this line to your application's Gemfile:
gem 'smart_kv'
Bug reports and pull requests are welcome on GitHub at https://github.com/styd/smart_kv. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.