Fork me on GitHub
#babashka
<
2020-03-25
>
pithyless11:03:58

What is the idiomatic way to read an edn file in bb? First attempt: (edn/read-string (slurp (io/file "deps.edn")))

borkdude11:03:49

@pithyless That's how I usually do it. I guess you can also do:

$ bb '(edn/read (.PushbackReader. (io/reader (io/file "/tmp/foo.edn"))))'
{:a 1}
which is more characters. There's nothing specific to bb about reading EDN files this way. However, you can also use an input flag to read EDN from stdin:
$ cat /tmp/foo.edn | bb -I '*input*'
({:a 1})

👍 4
teodorlu12:03:45

Will the PushbackReader approach avoid allocating a string of the whole file?

borkdude11:03:41

That is mostly for one-liners, for scripts I would do it with one of the former ways

borkdude11:03:10

oh this also works:

$ bb '*input*' < /tmp/foo.edn
{:a 1}

borkdude11:03:42

$ bb '(:a *input*)' <<< '{:a 1}'
1

borkdude11:03:19

with no input flags, the input is bound to EDN from stdin. With -I this changes to a lazy seq of EDN values from stdin.

teodorlu12:03:51

bb '(:a *input*)' <<< '{:a 1}'
1
I found this surprisingly aesthetically pleasing. I also noticed that you don't crash on "invalid EDN-format input" on stdin if I don't read *input*. Nice!

borkdude12:03:47

@teodorlu Note that this also allows piping EDN through multiple invocations of bb

borkdude12:03:45

$ bb -O '(repeat {:a 1})' | bb -I '(take 3 *input*)'
({:a 1} {:a 1} {:a 1})

teodorlu12:03:35

That's amazing! If you care for it, I'd love to read the code where you (I assume) prevent that first pipeline part from producing more than the 3 elements that are requested for the second pipeline part.

borkdude12:03:23

@teodorlu this code is mostly in babashka.main and it uses the PIPE signal to prevent reading any further

borkdude12:03:45

btw, it doesn't work on Windows where the PIPE signal isn't available with GraalVM native-image

nate16:03:27

@borkdude does sun.misc.Signal's presence in babashka mean we can handle signals in our scripts?

borkdude16:03:07

what's the use case?

nate16:03:06

I have a bb script that ends up running clojure -A:repl ... and I've found if I hit ctrl-c in the repl, the bb script exits and the child java process spins out of control

nate16:03:30

was thinking of trapping ctrl-c, cleanly exiting the java process, and then exit my bb script

nate16:03:21

I've never trapped a signal in java or clojure, just hoping that I have an avenue to pursue

borkdude16:03:16

Maybe there is something in ProcessBuilder to handle this cleanly? I'm also not very familiar with this

nate16:03:55

oh, good idea

nate16:03:02

I'll take a look at it

borkdude16:03:52

fwiw deps.clj also spawns a REPL but ctrl-C seems to work normal there

borkdude21:03:34

while making some progress on the nREPL server, I discovered that we didn't yet support *print-length*. that got added on master:

$ lein bb "(binding [*print-length* 10] (println (range)))"
(0 1 2 3 4 5 6 7 8 9 ...)

👍 12