Fork me on GitHub
#off-topic
<
2022-03-02
>
dpsutton20:03:22

does anyone have a handy bash snippet or function so that i can call clj -J$(socket-repl 50505) and it would expand to the correct incantation for a socket on that port? Aliases can’t quite do it, and i’m unsure how to “return” a string such that it works exactly right

dpsutton20:03:58

of course i have a few aliases but those are statically tied to a few ports. So for when using a jar or wanting a one-off port it would be quite helpful

Cora (she/her)21:03:03

socket-repl() {
  echo -n "-Dclojure.server.repl=\"{:port $1 :accept clojure.core.server/repl}\""
}

Cora (she/her)21:03:46

ah, wait, I think I see what you mean

dpsutton21:03:26

yeah. it’s easy to get the string correct but I just don’t know how to have it return a string to the original shell. keeps seemingly evaling it

p-himik21:03:36

Anything that you put in stdout in a function will be that function's return value. I'm not sure what you mean by "keeps seemingly evaling it". Cora's answer LGTM - the string will be put on the stdout, where $(...) will pick it up and substitute.

p-himik21:03:17

To demonstrate, I replaced clj with echo just to print its args:

p-himik@p-himik-pc:~$ socket-repl() {
  echo -n "-Dclojure.server.repl=\"{:port $1 :accept clojure.core.server/repl}\""
}
p-himik@p-himik-pc:~$ echo -J$(socket-repl 50505)
-J-Dclojure.server.repl="{:port 50505 :accept clojure.core.server/repl}"
p-himik@p-himik-pc:~$ 
Seems correct.

dpsutton21:03:19

❯ socket-repl() {
  echo -n "-Dclojure.server.repl=\"{:port $1 :accept clojure.core.server/repl}\""
}

/tmp/socket
❯ clj -J$(socket-repl 6000)
WARNING: Implicit use of clojure.main with options is deprecated, use -M
Exception in thread "main" java.lang.RuntimeException: EOF while reading string
	at clojure.lang.Util.runtimeException(Util.java:221)

dpsutton21:03:55

so i agree with you that it is trivial, but for some reason it isn’t working. Not sure if there’s some escaping somewhere that needs to be done

p-himik21:03:46

That's exactly why I hate shell languages and try to avoid them whenever possible. Bloody whitespace keeps messing things up. I think there should be double quotes around $(...).

p-himik21:03:16

So, try clj -J"$(socket-repl 6000)".

dpsutton21:03:18

❯ clj -J”$(socket-repl 6000)” Exception in thread “main” java.lang.ClassCastException: class java.lang.Character cannot be cast to class java.util.Map$Entry (java.lang.Character and java.util.Map$Entry are in module java.base of loader ‘bootstrap’)

p-himik21:03:50

Maybe those \" in the function aren't needed? No clue what clojure.server.repl needs.

p-himik21:03:45

Right, this works:

p-himik@p-himik-pc:~$ socket-repl() {
> echo -n "-Dclojure.server.repl={:port $1 :accept clojure.core.server/repl}"
> }
p-himik@p-himik-pc:~$ clj -J"$(socket-repl 6000)"
Clojure 1.10.3
user=> 

🎉 2
Cora (she/her)21:03:18

quoting -- it's never very fun

dpsutton21:03:23

no it is not. thank you all

💜 1
👍 1
dpsutton21:03:04

and works with java "$(socket-repl 6000)" -jar ~/projects/work/jars/0.42.0-rc1.jar amazing!

adi05:03:21

@U11BV7MTK late to the party, but see if this approach feels better. Using a sort of higher-order function like this sidesteps the problem of shell expansion-and-eval at the command line.

with_socket_repl() {
    local port=${1}
    local cmd=${2}
    local args=${@:3}

    ${cmd} \
        -Dclojure.server.repl={:port ${port} :accept clojure.core.server/repl} \
        ${args}
}
Test
with_socket_repl 1337 echo -jar ~/projects/work/jars/0.42.0-rc1.jar
If you've not used bash functions like standalone shell tools, https://www.evalapply.org/posts/shell-aint-a-bad-place-to-fp-part-1-doug-mcilroys-pipeline/#compose-again-semantics-functions-play-grand-new-pipeline... source 'em and tab-tab-complete your way to cmd-line glory 🤓

👀 1
adi05:03:06

P.S. Then one can also do silly stuff like...

with_1337_socket() {
      with_socket_repl 1337 ${@:1}
     }
and...
with_1337_socket echo -jar ~/projects/work/jars/0.42.0-rc1.jar