dry-rb / dry-container

A simple, configurable object container implemented in Ruby
https://dry-rb.org/gems/dry-container
MIT License
335 stars 41 forks source link

Add ability to iterate over items registered in a namespace #68

Open paul opened 4 years ago

paul commented 4 years ago

I have a use-case where I have several "parser" objects registered in a namespace within a container, and I'd like to iterate over each of those objects to find the first that works.

Examples

I have a container like this:

class MyContainer
  extend Dry::Container::Mixin

  namespace :parsers do
    register(:first)    { MyParser.new }
    register(:another)  { MyOtherParser.new }
    register(:fallback) { MyFallbackParser.new }
  end

  namespace :more_things do
    # ...
  end
end

In my code, I want to try each one till I get one that works:

MyContainer
  .namespaced(:parsers) # Something like this
  .lazy
  .map { |parser| parser.call }
  .detect(&:success?)
  .presence || Failure("no valid parser found")

I can work around it by doing:

MyContainer
  .each
  .select { |k,_| k.start_with? "parsers." }
  .map(&:last)

... but that seems more cumbersome than it needs to be.

Resources

@solnic asked my to open a feature request from this convo in zulip.

davydovanton commented 4 years ago

hey, I think it's a good idea and this functionality can be useful in other projects/gems. But I'm not sure that should we really add it to dry-container. @solnic @timriley WDYT folks?

solnic commented 4 years ago

But I'm not sure that should we really add it to dry-container.

@davydovanton why?

davydovanton commented 4 years ago

@solnic I think it can be useful in business logic more (just IMHO) and I'm not sure that it's a good idea to make dry-container more complex. Also, I see one good example of usage of this functionality in hanami (like use internal container Container['hanami.core'] or something like this, but in hanami we use dry-system). That's why I think it will be a good idea to implement it in dry-system's container. But it will be ok for me to implement it in dry-container too. I just want to say that I see it as a dry-system feature more.

timriley commented 4 years ago

This feature seems like the kind of generic functionality that would fit just fine in dry-container.

After all, dry-container already supports the idea of "namespaces" when it comes to registering entries, and we can already hack together a namespaced iteration like @paul demonstrates, so I think it'd be good to have in place here.

solnic commented 4 years ago

I agree, this should be implemented here.

flash-gordon commented 4 years ago

The potential problem is if some API depends on this feature you won't be able to swap the container with a plain hash or something else.

timriley commented 4 years ago

True, but I think that's something we can live with.

solnic commented 4 years ago

We already have features that are not available in plain Hash API and I don't think it was ever a requirement that Container must be replaceable by a plain Hash.