Comments (16)
Also,
find-keys
should default to:include-refsets? true
because a bunch of keys are left out on exec.
No, that part is deliberate. If you have a configuration:
{::a (ig/ref ::b), ::b 1}
Then if you want to initiate ::a
, you have to also initiate ::b
, because a ref must connect to exactly 1 key. However:
{::a (ig/refset ::b), ::b 1}
Because a refset can be empty, it's perfectly valid to initiate ::a
and not ::b
, therefore if you want ::b
it needs to be explicit.
From a practical perspective, this allows you to initiate an explicit subset of a refset.
from integrant.
This is a larger problem than it seems at first consideration. How can we tell whether a reflike behaves like a ref or a refset, and would adding more to the RefLike
protocol add more complexity than the functionality justifies? I think this needs to be given some further thought.
from integrant.
I think we need a little time to ensure that reflikes work consistently, so what I'll do is to create a new reflike
branch and revert #68 on master
.
However, I will rename the :include-refsets?
option to something like :optional-deps?
in order to not tie it to refsets in particular. As I doubt many (if any) people are using this and Integrant is yet to hit 1.0, I'm okay with a breaking change in this case.
I'm thinking that we may want to have two additional protocol functions on reflike: ref-deps
and ref-mandatory-deps
, which take a collection of keys from the configuration, and return only the keys that the ref depends on.
from integrant.
Also, find-keys
should default to :include-refsets? true
because a bunch of keys are left out on exec. Sample:
(def config
{:some/handler 1
:some/other 2
:jetty/server (ig/refset :handler)})
(def system (ig/init [:jetty/server]))
;; => init ... build ... dependent-keys ... find-keys
;; => just :jetty/server ends up in the map
from integrant.
Naming of this config option is a bit misleading, it's called
:include-refsets?
but what it actually does is:include-reflikes?
Yes, that looks like a mistake. Let me think of the best way to handle this... perhaps via a :ref-filter
option instead.
from integrant.
I guess there are 2 possible behaviors: lazy/minimal or greedy/maximal.
Note, the (current) lazy/minimal one makes duct core's default (exec-config config profiles [:duct/daemon])
initializer not-very-useful, in a {:duct/daemon (ig/refset :my/handlers)}
scenario - no handlers get loaded and the program doesn't do anything useful.
from integrant.
The minimal strategy allows you to exclude keys from a refset, whereas a maximal strategy does not. With a maximal strategy you'd need to either lose functionality, or change how the keys are specified.
Now it's true that in that particular case, the Duct default isn't a good one. But that's a very specific use case, and I think if you're going to do something unusual, overriding the default to something like [:duct/daemon :duct/handler]
isn't that burdensome a task.
Plus the way Duct is currently written, profiles and modules rely on the minimal strategy in order to define ordering. With a refset you can effectively say "if this key exists, ensure you come after it".
from integrant.
Whether we call the option :eager
or :optional-deps?
, we still need some way of determining which dependencies are optional for a reflike, and which dependencies are mandatory. In other words, we need two functions:
(ref-optional-deps reflike keys)
(ref-mandatory-deps reflike keys)
Or possibly:
(ref-all-deps reflike keys)
(ref-mandatory-deps reflike keys)
from integrant.
Sorry, I deleted my prior comment because it was bonkers, before you replied.
Yes, we need to change RefLike as you mentioned.
The case I'm making now is for :include-refsets?
/:include-reflikes?
/:optional-deps?
to be toggle-able from ig/init
- down the call chain - up to dependency-graph
; while at the same time keeping the functions signatures reasonable. At the moment this is my main concern.
from integrant.
My thoughts come and go; to go back at my earlier (deleted) point (not all bonkers), better stated:
In the great scheme of things a reflike can:
- get precisely one thing (ref) off the map
- get zero or more - anything else (reflike, refmap, refwhatever, anything else but the above).
In light of this, optional/mandatory is a complication; whether this is a distinction that's needed, we have yet to have a concrete case.
So rename to :include-reflikes?
and keep RefLike signature seems sufficient to me. (Plus toggle-able from ig/init
as stated above.)
from integrant.
Let me know on which variant you're sold and I'll sketch a PR.
from integrant.
The case I'm making now is for
:include-refsets?
/:include-reflikes?
/:optional-deps?
to be toggle-able fromig/init
- down the call chain - up todependency-graph
; while at the same time keeping the functions signatures reasonable. At the moment this is my main concern.
I don't think we need that. It's more straightforward to just be explicit about the keys you want. Automatically including dependencies was only ever intended to pull in mandatory dependencies; i.e. it automatically includes the minimal set of keys that conform to what the user requires.
So rename to
:include-reflikes?
and keep RefLike signature seems sufficient to me. (Plus toggle-able fromig/init
as stated above.)
I don't think that's a good idea. Remember, anything we implement is going to be set in stone. We cannot remove options or behavior after Integrant hits 1.0, which ideally I'd like to do sometime this year.
This also sets up special, hardcoded behavior for refs over other RefLikes. Again, this doesn't strike me as good design; ideally I'd like RefLikes to be consistent in how they behave.
from integrant.
I don't think we need that.
I arrived here wanting a way for (ig/init [:my/server])
to pull in all my :handlers
.
It's more straightforward to just be explicit about the keys you want.
Say, handlers are in the hundreds or more, and added somewhat dynamically by a mechanism. Not quite straightforward, nor do I like it.
It's ergonomic in EDN to declare deps as {:my/server (ig/refset :my/handler)}
rather than be explicit about each handler; also the latter not as feasible in my "mechanism" case above.
I'll leave this alone for now, but likely come back to it later. This is the main reason for this ticket.
I don't think that's a good idea.
Ok, continuing with the "optional/mandatory" variant, I'll try to have a PR soon; sketch:
- RefLikes have it in them to decide what's mandatory or optional; protocol:
(defprotocol RefLike
(ref-key [r] "Return the key of the reference.")
(ref-mandatory-keys r config "Returns the mandatory keys from `config`.")
(ref-all-keys r config "Returns the mandatory and optional keys from `config`.")
(ref-resolve [r config resolvef] "Return the resolved value."))
find-derived-refs
usesref-mandatory-keys
orref-all-keys
depending on:optional-deps?
flag.
from integrant.
Say, handlers are in the hundreds or more, and added somewhat dynamically by a mechanism. Not quite straightforward, nor do I like it.
It doesn't matter how many handlers there are, as long as their keys share an ancestor. So for instance you might write:
(ig/init config [:duct/daemon :my/handler)])
If you're using refset
to pull in all your handlers, then you must have already created a common ancestor. By specifying the :my/handler
key to initialize, you also initialize all derived keys.
Alternatively, you could create a custom RefLike where all of the keys are mandatory.
RefLikes have it in them to decide what's mandatory or optional; protocol
Unless I've missed something, I don't think the ref-mandatory-keys
and ref-all-keys
need access to the configuration. They just need a collection of keys to choose from.
from integrant.
I've added a reflike
branch for pursuing this feature. I'll revert the change in master
when I have time to resolve all the conflicts, with the intent of introducing the reflike feature into a 1.1.0-alpha.
from integrant.
Let's release reflike.
from integrant.
Related Issues (20)
- Uninitialized/literal configs HOT 1
- Tests don't run with 1.11 due to clojure.test/run-test already being defined HOT 1
- Access to Enter Integrant presentation HOT 2
- Clarity on handling prod/dev config HOT 1
- ClojureScript support for `read-string` HOT 4
- Initialisation Order HOT 5
- Decouple top-level keys from configuration type definitions HOT 9
- [Feature] Ability to provide custom hierarchy to `init` method HOT 6
- Would you consider an integrant2 to support extensible build steps? HOT 10
- Why does resume halt unspecified system keys? HOT 4
- Support usage in Babashka environments HOT 20
- #{:idea} Pass the spec validations step on all defined states before calling init-key. HOT 1
- is it possible to access a component after it's init-key, but before it gets passed to the next key that depends on it? HOT 2
- Enter Integrant Video
- Add support for custom assertf definitions HOT 2
- Question: Extract "validation keys" logic from core/build implementation HOT 4
- Feature request: pre-init hook
- No method in multimethod 'init-key' for dispatch value HOT 2
- #ig/ref should allow for deep references HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from integrant.