Fork me on GitHub
#mount
<
2016-01-21
>
bbss07:01:16

@tolitius: Boot App Version: 2.0.0 Boot Lib Version: 2.1.2 Clojure Version: 1.6.0 But it's okay, I've been using mount on my own project successfully so far simple_smile

tolitius14:01:07

@bbss: great, thanks for the feedback. This is probably minor then, but whenever you have a chance, could you try to upgrade boot (`2.0.0` is a bit old):

$ boot -u
Retrieving boot-2.5.5.jar from 
#
#Thu Jan 21 09:18:36 EST 2016
BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_VERSION=2.5.5
BOOT_CLOJURE_VERSION=1.7.0
and do boot cljs-example?

jrychter20:01:12

I'm transitioning to mount and slowly getting the hang of it. But I'd like to ask for some guidance. I have a namespace app.config where normally I used to keep a config atom. This gets initialized with config data read from a file. Problem is, the filename is normally supplied from the command line, in my app.main namespace's main function. What is a reasonable way of passing that filename to app.config defstate functions?

jrychter20:01:16

Also, is the :refer [config] magical in some way, or will mount work just as well with (:require [my.namespace]) and calling my.namespace/accessor?

jrychter20:01:56

@tolitius: I don't know how I missed that when reading the docs…

tolitius20:01:13

:refer [config] is same as Clojure: i.e. my.namespace/accessor would also work

tolitius20:01:40

@jrychter: it's the last thing.. I might need to reorganize the docs a bit

jrychter20:01:15

Ok, the mount/start-with-args approach could work. I don't yet see how to make this elegant (e.g. only pass a limited number of well-behaved arguments to mount), but I just need to think about it.

jrychter20:01:26

Yes, in general I think the docs could be improved. I found them difficult to follow and understand and I think this is preventing people from using mount. Please take this as an observation, rather than critisism, I don't want to sound rude or ungrateful.

tolitius20:01:48

are all the config values in the external config file, or you are looking to overwrite some of the values in config with something like -D?

tolitius20:01:28

@jrychter: not at all, great feedback. what (re)organization would you feel help the most?

jrychter20:01:32

No, the idea is that I just pass the filename. The config ns deals with everything else, such as creating the file if it doesn't exist, or reading configuration from an existing file. So it's just one string-or-nil value.

jrychter20:01:22

As for docs, when I was reading them, I thought: that's a strange way to begin. For example, they begin by outlining differences from component, which I don't really care about unless I'm comparing the two. But to compare, I have to learn how mount works anyway, so…

jrychter20:01:46

I think I expected a short outline of the mount approach and then a meaningful reasonably complete example.

jrychter20:01:25

I write a lot of documentation, so perhaps if I learn to use mount, I could contribute a gentle introduction.

jrychter20:01:37

Also the 'Value of values' section seems superfluous — I found the behavior obvious. Am I missing something? This is exactly what I expected, so I couldn't understand why there was a section on it.

tolitius20:01:36

simple_smile great. I agree with "a short outline and reasonably complete example", feels more effective. I did include component there because a lot of the people use component, and would be questioning why they need mount. I think it is logical to remove it a bit later, when mount is as familiar (which is slowly happening) "value of values" this was not possible in earlier versions of mount ( https://github.com/tolitius/mount/issues/20 ), and a couple of people asked this would be documented

jrychter20:01:20

I think in general the documentation is complete, it's just the structure and ordering which can be confusing to newbies like me.

tolitius20:01:43

the example is there: https://github.com/tolitius/mount/tree/0.1.9-SNAPSHOT#mount-and-develop a ""a short effective outline" would definitely help

jrychter20:01:49

So, do I understand correctly that mount/start-with-args can take any value, such as a map with options that I want to pass to my components?

jrychter20:01:08

Yes, the example is actually how I figured out how to use mount.

tolitius20:01:10

yes, mount/start-with-args can take any value.

jrychter20:01:26

Though I think it could immediately be enhanced by adding my use case to this https://github.com/tolitius/mount/blob/0.1.9-SNAPSHOT/dev/clj/app/conf.clj (passing the config file name through mount/start-with-args

jrychter20:01:06

I actually need the ClojureScript one immediately simple_smile All my apps are Clojure + ClojureScript. And the one I'm migrating is fairly large on both sides — it's https://partsbox.io/

jrychter20:01:43

I began on the Clojure side, because it's slightly easier and there are better debugging tools.

tolitius20:01:52

right, so this file name (i.e. "dev/resources/config.edn") maybe the only thing you pass via -D, and then something like:

(defstate config 
  :start (load-config (:config-path (mount/args))))
would work

tolitius20:01:47

where it would be pass as (for example) -Dconfig-path=xyz/resources/config.edn

jrychter20:01:43

I'm reworking my configuration and trying things out as we speak.

tolitius20:01:11

looks cool simple_smile

jrychter20:01:43

BTW, I clicked on the ClojureScript docs immediately, read about derefing, then jumped into Clojure and was surprised that derefing doesn't work simple_smile

tolitius20:01:01

yea, if you need to use mount in both Clojure and ClojureScript I would recommend reading: https://github.com/tolitius/mount/blob/master/doc/clojurescript.md#managing-state-in-clojurescript

jrychter20:01:28

This is exactly what I started with.

jrychter20:01:21

Oh, a practical observation: it was (and still is) unclear to me where the (mount/in-cljc-mode) form needs to be placed.

tolitius20:01:28

oh.. ok. yes, (mount/in-cljc-mode) will switch mount into a mode of derefing. All APIs are going to work consistently between clj and cljs.

tolitius20:01:01

anywhere before (mount/start)

jrychter20:01:04

So where does it go? In both Clojure and ClojureScript code (my code isn't cljc)

tolitius20:01:36

sure, cljc is just a name to indicate that it supports both.. I guess it might be too geeky of me simple_smile

jrychter20:01:37

…and (I think this is what the docs say) does this mean that I will be using @ to access Clojure state as well?

jrychter20:01:22

So I should call (mount/in-cljc-mode) both in my server-side app and in ClojureScript code, anywhere before (mount/start) to get the same API in both worlds.

tolitius20:01:32

yes, in case you need to work in both modes, I would recommend to call (mount/in-cljc-mode) at the app entry point, and use @ to access your states (there is a cljs app example). (!) you don't have to do that at all, and work without @ in both clj and cljs, but you might have problems with cljs :advanced optimization mode. this was the sole driver for this mode

jrychter20:01:06

Actually, I really prefer that mode. Even for aesthetic reasons, I find @ logical to use in case of state.

jrychter20:01:20

And I do need :advanced very much simple_smile

tolitius20:01:50

right.. this is from docs (with one of the points you agree with already): While initially it may sound strange, this approach has very nice properties: * Mentally something that you deref (@) is associated with a state behind it * The whole system may start lazily without an explicit call (mount/start) * States may have watchers which is just an idea at this point, but it could be quite useful

jrychter20:01:24

I fully agree and I don't think this sounds strange at all. I always had state encapsulated in atoms, and always used @ to access it.

jrychter20:01:18

Sigh. I regularly break things completely by making an error in the :stop function, which means I can't stop the system, which means I can't reload the namespace simple_smile

tolitius20:01:18

in the REPL, you could get a reference to the sate var, and stop it manually

tolitius20:01:30

for example, say you have a web server as a state:

tolitius20:01:53

(defstate web-server :start (...) :stop (.. with error ...))

tolitius20:01:23

when you call (mount/stop), the :stop of the web server would error out / or won't stop the server

tolitius20:01:32

from the REPL you can do:

tolitius20:01:47

(require '[myns :refer [web-server]])

tolitius20:01:02

(.shutdown web-server)

tolitius20:01:13

i.e. if .shutdown is a correct way, of course

tolitius20:01:58

answering your previous question: on the cljs side you don't need to call (mount/in-cljc-mode)

jrychter20:01:24

Oh, ok. See, this is what is missing in the docs simple_smile I think they should simply say: in Clojure code, call (mount/in-cljc-mode) before (mount/start), which will change the API so that you will need to deref (`@`) state.

jrychter20:01:58

Thank you for all your help, and thank you for writing mount, which I really like so far. Once I get comfortable using it, I will try to contribute to the documentation.

tolitius20:01:49

sure, that'd be great, thank you simple_smile