This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-17
Channels
- # bangalore-clj (1)
- # beginners (23)
- # boot (141)
- # cider (68)
- # cljs-dev (29)
- # cljsjs (1)
- # cljsrn (11)
- # clojure (150)
- # clojure-austin (3)
- # clojure-berlin (1)
- # clojure-france (2)
- # clojure-greece (13)
- # clojure-italy (5)
- # clojure-russia (49)
- # clojure-spec (15)
- # clojure-uk (45)
- # clojurescript (152)
- # code-art (1)
- # core-async (75)
- # cursive (12)
- # datascript (2)
- # datomic (90)
- # dirac (5)
- # emacs (10)
- # garden (1)
- # hoplon (52)
- # instaparse (4)
- # juxt (2)
- # lein-figwheel (2)
- # lumo (47)
- # mount (94)
- # off-topic (20)
- # om (21)
- # onyx (14)
- # parinfer (19)
- # pedestal (3)
- # protorepl (13)
- # re-frame (5)
- # reagent (20)
- # slack-help (10)
- # spacemacs (8)
- # specter (57)
- # unrepl (11)
- # untangled (3)
- # vim (1)
- # yada (1)
If I remember correctly, Boot (aether) only pulls the pom files for each version
And this might be because you depend on some library which has dependency on the other clojure version, or even some package which uses version range to depend on Clojure, which I think causes aether to download ~all pom files
version ranges are generally frowned upon in pom.xml files that are uploaded to a public repo
I keep defending boot, I still have colleagues who are not convinced about the switch (but in this case I’m not completely sure if lein does absolutely the same thing)
I think this should work the same in Lein and Boot
But there is still some room for differences/bugs, like https://github.com/boot-clj/boot/issues/577
It seems quite random, sometimes I see the correct versions and sometimes not
Random across different days, perhaps different dependencies
But running two times in row give the same results
@micha Btw, did you see my solution to moving exceptions (and other data) between pods: https://github.com/boot-clj/boot-cljs/blob/master/src/adzerk/boot_cljs/util.clj#L46-L75
This should work for all throwables, all Clj datastructures, Dates etc.
One problem I found was Less4J error classes, which don't extend Serializable
(The exception itself is serializable, but it has properties which are not)
wait so objectoutputstream serialization can correctly serialize clojure data across clojure versions for example?
Or well, I haven't tested between two versions, but works between two classloaders at least
that is what it is used for
for Java RMI or something
or if it's a native java object (like from the bootclassloader) it just passes it through
Aha, I also implemented similar solution to Boot-cljs which created Exceptions using reflection
What does that Stash do?
boot.user=> (def p (boot.pod/make-pod (get-env)))
#'boot.user/p
boot.user=> (def e (try (boot.pod/with-pod p (throw (Exception. "foop"))) (catch Throwable ex ex)))
#'boot.user/e
boot.user=> (type e)
java.lang.Exception
boot.user=> (.getMessage e)
"foop"
so the both pods are dealing with the same object rather than one pod making a copy of what is in the other pod
Okay. But yeah, the problem is not passing the java classes which are shared, but the problem is when those objects contain Clj objects which can't be passed straight throughh
I wouldn't worry much about serialization changing between clojure versions, e.g, PersistentHashMap properties haven't been changed in 7 years,
boot.user=> (boot.pod/with-pod p (def xxx 100))
#object[clojure.lang.Var 0x46f62c15 "#'pod/xxx"]
boot.user=> (def f (boot.pod/with-pod p (fn [x] (+ x xxx))))
#'boot.user/f
boot.user=> (f 100)
200
hm how would that work?
oh right, both calculations are inside the pod
^ re Java Serialization and changing the classes
I think this kind of data passing is usually only needed from task pod -> main pod
Or well, currently I think I pass all file paths as strings to task impl
Could be useful to use File's
But mostly the serialization is interesting for cases where it is not possible to know what data is passed between pods
like Cljs exception data
It would be easy to just select the few interesting fields for use in boot-cljs/reload
but Figwheel presumes that the exception is the same as from Cljs compiler
no, but maps with all the same fields
and different errors and warnings have different metadata, files etc.
in one case the compiler state is atteched to warning metadata, that breaks the serialization because it has (I think) circular reference to itself
Except functions are serializable
I think Clj functions create a class that extends AFunction? https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFunction.java
Not sure if this really works between classloaders, but serializing function returns something and deserializing that returns a function
(def foo 100)
((deserialize-object (serialize-object (fn [] {:x foo}))))
;; => {:x 100}
Okay, doesn't really work between classloaders
I think fn
returns something which is serializable and refers to the real function
boot.user=> (def a (atom 100))
#'boot.user/a
boot.user=> (defn f [] (swap! a inc))
#'boot.user/f
boot.user=> (f)
101
boot.user=> (def f' (serialize-object f))
#'boot.user/f'
boot.user=> (type f')
java.lang.String
boot.user=> (def g (deserialize-object f'))
#'boot.user/g
boot.user=> (type g)
boot.user$f
boot.user=> (g)
102
boot.user=> (g)
103
boot.user=> (g)
104
boot.user=> (g)
105
(def p (boot.pod/make-pod))
(boot.pod/with-eval-in p
(import [java.util Base64]
[ ObjectOutputStream ByteArrayOutputStream])
(defn serialize-object
"Serialize given Object to String using Object Streams and encode the bytes
as Base64 string."
[e]
(with-open [bos (ByteArrayOutputStream.)
out (ObjectOutputStream. bos)]
(.writeObject out e)
(.encodeToString (Base64/getEncoder) (.toByteArray bos)))))
((deserialize-object (boot.pod/with-eval-in p
(def foo 100)
(serialize-object (fn [] {:x foo})))))
;; java.lang.ClassNotFoundException: pod$eval56$fn__57
Deserialization fails as the class created by fn
is not found in another classloader
Yeah, I was surprised it works at all
when you cal lthe function it uses reflection to call it with args that are translated into things that are from the pod the function was created in
it's funny, you can pass functions back and forth between the pods as many times as you want, it will keep building more layers of proxies
now, I have another question: Can I (probably I can, but should I) override the repl task? Use case: when I get into repl in 99.5% cases I need to kick-off cljs compilation (what could go wrong if I rename boo.core/repl, create another repl task and pass all given args into repl*
that composed with cljs
?
@ag I've found the only reason to want to override boot repl is for cider. But you can customize the start task to be dev
which is an idiom in boot.
dominicm: do you override "repl" or just add a cider task? i follow the advice in "a better way" at https://github.com/boot-clj/boot/wiki/Cider-REPL, but that does not override anything, it just adds a task.
mobileink I add the cider task, and just run either boot cider repl
or boot cider dev
as appropriate
@U0LGCREMU I don't understand that
I try and keep things kinda "raw" I don't worry too much about beginners. I concentrate more on educating on the basic concepts which make the reasoning behind additional cider tasks & such make sense.
I suppose that > I don't worry too much about beginners would be better worded as "I don't worry much about making things easy for beginners."
when you add a cider task, you"re not overriding anything. just putting another task in the pipeline. the repl task is unchanged
Yeah. I don't override things if I can help it. I've only been inclined when hearing the easy argument from cider users.
@dominicm cider’s default value for cider-boot-parameters
is "repl -s -H :: wait”
having .dir-locals.el
that sets the value right is not very “user friendly”. I was thinking if I can improve that
I find that interesting. As a vim user, that idea doesn't even remotely bother me. I've never had anything like cider-jack-in. I find it simpler to run boot/lein as appropriate, then vim connects to the nREPL that is opened. It's exactly the same.
tell us exactly what he did that resulted in that very impolite msg, and we will fix it. pretty sure.
alright… this scared me for a moment (there’s already heated discussion and I’m in minority defending boot). Turned out the colleague long-long time ago experimented with boot, and boot
was actually pointing to the older executable.
boot is awesome