dry-system 0.23.0 is out, and 1.0.0 is around the corner — please give it a test!

Hi folks, tonight we’ve just released dry-system 0.23.0, a major advancement for the gem that puts in place nearly everything we want for a 1.0.0 release, which is now just a matter of a month or two away.

If you’re a dry-system user, we’d really appreciate it if you could upgrade to 0.23.0 soon, and give us any feedback you think we should hear as we prepare for 1.0.0.

Thank you very much!

Tim & the dry-rb team

My team has been working on a greenfield API service since last year, and we chose to make a clean break with Rails and give dry-system a shot.

This is a great update. Really clarifies the language around what providers are for, and the distinction between internal and external providers. We’re already running on 0.23 and the update was easy.

I chose to make certain decisions about module namespace and autoloading that didn’t quite fit with dry-system’s default behavior, so I have some customized autoloading. We moved to using the zeitwerk plugin but still require a custom loader. So far the update made our customizations simpler.

The slight API difference between Zeitwerk’s camelize and dry-inflector’s camelize is a shame, had to build a simple translation interface. Not a big problem, just a rough edge.

Three big areas that are undocumented or under-documented:

  1. Plugins. What’s the distinction between an external provider and a plugin, how are they different, when would you choose one over the other.
  2. Callbacks. The precise timing and behavior of callbacks is a big question mark to me. I understand that they changed a bit with this release but I don’t quite follow why. When do callbacks execute, what is their execution environment, and why would you choose to use them?
  3. What belongs in the app container and what doesn’t. I initially tried to put everything in the container including the inflector, autoloader, and router. Following Hanami’s lead I have pulled back on that. I think a little more guidance here would go a long way.

Due to the interaction of the inflector and autoloader, timing is really important on when they get initialized. I was resistant to building the inflector inline with the config because of the verbosity, but that ended up creating a lot of problems. I’ve since moved to loading our inflections from YAML config to streamline the configuration code.

module InflectYAML
  refine Dry::Inflector.singleton_class do
    def load_file(filename)
      config = YAML.safe_load_file(filename, symbolize_names: true)

      new do |inflect|
        %i[acronym uncountable].each do |type|
          Array(config[type]).each do |item|
            inflect.public_send type, item.to_s

        %i[plural singular].each do |type|
          Array(config[type]).each do |item|
            inflect.public_send type, *Array(item)
1 Like

I actually thought about it few times before. Basically, inflector is an underlying lib for things like zeitwerk or some ORM/Routers and team may really consider to make a steps toward them, like adding a second parameter for compatibility