dry-container
dry-container copied to clipboard
Add ability to iterate over items registered in a namespace
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.
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?
But I'm not sure that should we really add it to dry-container.
@davydovanton why?
@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.
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.
I agree, this should be implemented here.
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.
True, but I think that's something we can live with.
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.