(if (seq cols) (apply map + cols) <whatever other value you want>)
Or throw an exception perhaps if it “shouldn’t happen”.
Okay! Thank you! 😄
If you want an exception and you don’t care about getting a lazy seq of sums, you could just (apply mapv + cols)
— it will throw an arity error if cols
is empty.
Also by any chance do you have example projects using clojure.tools.cli
? Am trying to use it but another reference might help
I don’t know what will be more useful than the examples in the README but clj-new
still uses it (even though the old -m
command-line is no longer documented). See https://github.com/seancorfield/clj-new/blob/develop/src/clj_new/helpers.clj#L264 for the opts definitions and https://github.com/seancorfield/clj-new/blob/develop/src/clj_new/helpers.clj#L381 for the point of use.
Cognitect’s test-runner
uses it too, starting at https://github.com/cognitect-labs/test-runner/blob/master/src/cognitect/test_runner.clj#L77
(although that uses :assoc-fn
in places where I’d use :update-fn
now)
See this example from tools.cli
’s README for what I mean about that:
["-f" "--file NAME" "File names to read"
:multi true ; use :update-fn to combine multiple instance of -f/--file
:default []
;; with :multi true, the :update-fn is passed both the existing parsed
;; value(s) and the new parsed value from each option
:update-fn conj]
Hi, I'm trying to apply the bean
function over java.net.URL
but I'm getting this error:
(bean (java.net.URL. "<https://localhost:80>"))
Error printing return value (ConnectException) at java.net.AbstractPlainSocketImpl/doConnect (AbstractPlainSocketImpl.java:399).
Connection refused (Connection refused)
Anyone can say why this is happening?(bean (<http://java.net|java.net>.URL. "<https://www.google.com>"))
shows it has :content
on it. If you look at the error thrown by your function you'll see [java.net.URL getContent "URL.java" 1177]
in it. And you presumably don't have a webserver running locally on port 80
hmmmm, thank you @dpsutton
(slurp (.getContent (<http://java.net|java.net>.URL. "<https://www.google.com>")))
is the contents of the resource
Yes, the bean
function walks over every getter and returns a map.
This is why I'm getting this error. Thank you again @dpsutton
I think i'm generally just a bit confused about how to package my project into a binary (?) or rather I need to read up more cause I have been pretty much only been using lein run
@seancorfield I think me asking this would help. Is
my-program -vvvp8080 foo --help --invalid-opt
the equivalent of running the following in the repl ?
(-main "-vvvp8080 foo --help --invalid-opt")
This is from the quickstart example. I've been particularly confused about how to get that working
They should be separate strings.
(-main "-vvvp8080" "foo" "--help" "--invalid-opt")
-main
expects to be called with a sequence of zero or more strings
Right right :face_palm: i recall a similar confusion I had when working with clojure.java.shell/sh
Thank you!
Just describing my dog in Clojure. Not totally sure if I’m doing this right lol. One area is I want to also describe his reaction to the :triggers but not sure what to do there
@rob370 seems fine ? Are you perhaps thinking of the triggers being functions?
Is there a way to print out a table when you do lein run
? I know there is clojure.pprint/print-table
but is there a direct that to cli output?
nvm I just realised it is because I was getting a clojure not found error from not requiring the namespace
You could use a (partial reduce + 0)
which will give you a zero if you have an empty sequence in the coll
How do I compile a leiningen project? Like I can do lein run
to use my program. And I understand I can do lein uberjar
but have a feeling that's not what I want exactly?
What do you want?
I think I want a simple way to allow someone to package my repo and run it as an executable. I think https://github.com/BrunoBonacci/lein-binplus comes close
Oh i think I can just include it in my project.clj hmm
It depends on your audience then, I usually take an uberjar to mean that, but if your audience is less technical then you will need something additional like that lein plugin
How do you run an uberjar actually?
java -jar uberjar.jar
That depends too
You can build jar files that launch like that
But java only knows how to run jvm bytecode, so you either have to hand it jvm bytecode (by aot compiling clojure) or bootstrap (run some bytecode that knows how to load clojure)
Hmmmm, will have to dig deeper into that but lein bin
works well for now java -jar
worked too for the standalone.jar that was produced
what is the meaning of :*
in Clojure?
it is a normal keyword, nothing special about it
I have a map with thousands of entries and want to find a value of an entry that has my search-value in a nested structure. for example this json:
{
"id": "nord-finance",
"symbol": "nord",
"name": "Nord Finance",
"platforms": {
"ethereum": "0x6e9730ecffbed43fd876a264c982e254ef05a0de",
"binance-smart-chain": "0x6e9730ecffbed43fd876a264c982e254ef05a0de"
}
},
{
"id": "norse-finance",
"symbol": "nfi",
"name": "Norse Finance",
"platforms": {
"binance-smart-chain": "0x43f001914c7d347d152f296e8539086fe49f8bd6"
}
},
{
"id": "northern",
"symbol": "nort",
"name": "Northern",
"platforms": {}
},
{
"id": "nosturis",
"symbol": "ntrs",
"name": "Nosturis",
"platforms": {
"ethereum": "0xeccf15a4b5976a1365baed5297058b4ca42777c0"
}
},
I want to search for the value "0x43f001914c7d347d152f296e8539086fe49f8bd6" in all etherum platform entries and have the id where this unique value is matched. Do I have to iterate through the whole thing?yes
unless you build an index data structure that allows for faster access
aka stick it in a database and let the database do the heavy lifting
I did this with the list for now:
(get (first (filter #(= (get-in % ["platforms" "binance-smart-chain"])
"0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82")
all-coingecko-coins)) "id")
while all-coingecko-coins is the json turned map from chesire. Is this a lot slower than a database, when I do this a lot?Besides using a database, you can also create a Cloure map in memory with the keys being the strings you want to search for, and the values being the entire original map {"id": ...}
(including the "ethereum"
key -- there isn't really any reason to remove that)
That would be one concrete example of 'building an index data structure that allows for faster access' that ghadi mentioned.
iterating through a list that is in the thousands is not going to be an issue
it all depends on the wider use-case. Doing this in a service? cardinality is actually in the millions+? etc.
I though about scaling this up. This is for the translation of one api-id-value into another. so I could just do it once, save it and be done
I could transfrom the whole json to "contractAdress" as a key and the id as a value map. Is this what you mean @andy.fingerhut?
yes, an index
txid -> tx
a map of ^
You can change the JSON file if you wish, and have that option, but it is straightforward in Clojure to create the in-memory map with whatever key you want, or even multiple maps with the same Val’s but different keys - whatever you want to search on most often
I have the following let in hiccup:
(let [jobinfo @(rf/subscribe [:jobinfo])
[:div
[:h4 (.now js/Date)]
[:pre (with-out-str (pp/pprint jobinfo))]])
The jobinfo
updates just fine in re-frame, but the js/Date
is not updated when the jobinfo is updated. How do I fix this?React might be caching the h4
, I’d try
(let [jobinfo @(rf/subscribe [:jobinfo])
now (.now js/Date)]
[:div
^{:key (str "jobinfo-date-str-" now)}
[:h4 now]
[:pre (with-out-str (pp/pprint jobinfo))]])
or something similarDid not work. I remember reading about this in some book about Clojure web programming - will find the answer 🙂
Thanks btw
I am trying to figure out a way to use [cheshire "5.10.0"]
in my REPL. Is there a best way of doing this? Can I add it as a global dependency?
I want to be able to do this in the REPL:
(cheshire/parse-string
(slurp "<https://jsonplaceholder.typicode.com/todos>"))
Any help would be appreciatedDo you know if you are using Leiningen, e.g. you have a file named project.clj
in your project? Or perhaps the Clojure CLI tools, e.g. there is a deps.edn
file in your project?
I am using leiningen - should have mentioned that
I tried using lein repl and it worked. I was using clj to start the repl for no real reason. Thanks!
They use different files to specify the dependencies of your project, but they can also be started even if the file they look for is not present. It is just in that case it will not notice the file of the other tool
You could choose to sometimes use one tool for a project, sometimes the other, but it would be your responsibility to keep their dependencies consistent between those two files in that case.
clj -Sdeps '{:deps {cheshire/cheshire {:mvn/version "5.10.0"}}}'
if you just want a quick REPL anywhere with Cheshire without worrying about deps.edn
There’s a useful plugin for Leiningen called lein-try
that lets you do a similar thing:
Add this to the :user
profile in your ~/.lein/profiles.clj
file:
:user {:plugins [[lein-try "0.4.3"]]}
and then you can do:
(! 1418)-> lein try cheshire/cheshire 5.10.0
...
user=> (require '[cheshire.core])
nil
all very useful - I'll save these to my terminal commands .txt file 🌝
clj -Sdeps '{:deps {cheshire/cheshire {:mvn/version "5.10.0"}}}' This command creates a temporary dependency that only lasts until you close the REPL?
Can someone please help explain what is going on here?
I have some tests and assertions defined in (deftest)
My file has (run-tests)
at the end and I'm running the test by doing Load Current File and Dependencies
IF I run the tests I see this:
; Evaluating file: interpreter-tests.cljs
Testing test.interpreter-tests
Ran 2 tests containing 16 assertions.
0 failures, 0 errors.
If I make one of them so that it fails I see this:
FAIL in () (interpreter-tests.cljs:90:9)
add adds
expected: (= {:registers {:a 17, :b 7}, :internal-registers {:par 0}} (math-func :add {:registers {:a 5, :b 7}} [:a 9]))
actual: (not (= {:registers {:a 17, :b 7}, :internal-registers {:par 0}} {:registers {:a 14, :b 7}, :internal-registers {:par 0}}))
Testing test.interpreter-tests
Ran 2 tests containing 16 assertions.
0 failures, 0 errors.
Why does it still say at the end ran 2 tests containing 16 assertions. 0 failures, 0 errors ?
Why doesnt it class my failing test as a failure?You probably want (test-ns *ns*)
instead of (run-tests)
.
The clojure.test
API is pretty strange in terms of what each (similar) function does in terms of fixtures and reporting. Many of the public functions are really low-level pieces that the other functions call — and are more useful to 3rd party test runners.
One of the differences here is that (test-ns *ns*)
“Internally binds *report-counters*
to a ref initialized to *initial-report-counters*
. Returns the final, dereferenced state of *report-counters*
.” which I don’t believe (run-tests)
does.
Does that help @qmstuart?
yes, thaats perfect, thank you
(that said, I don’t see the behavior you’re seeing when I try (run-tests)
in a REPL so I may be wrong)
changing it to use (test-ns)
, I now see it reporting failure count i would expect
OK, good.
Wouldn't (run-tests)
probably just map (test-ns)
over the namespaces?
Interestingly, run-tests
seems to call test-ns
… yes @emilaasa
actually no, I'm being dumb It isn't. It doesnt report the counts at all. But it shows the fails.
I’m just looking at the source… so many of these functions call each other with different setups 😐
ok, i restarted my repl and now i see correct counts. So maybe my file wasn't synced correctly or something.
How should I run tests?
There are plenty of earmuffs in that file - still if you reload your buffer I'd expect it to work
my problem is, I add tests and I want to run them. But sometimes I forget to evaluate them in the repl, then i dont see the pass / fails as I would expect
so I put (run-tests) or now (test-ns) at the end and just evaluate whole file
but maybe this isnt best way
Yeah, I think I have it backwards — I actually use run-tests
when running tests in a namespace, sorry.
What editor are you using? The ones I've used have had some hooks that probably call (run-tests)
under the hood
i'm using calva
Hm and you were doing cljs?
yes
Maybe wont work then
Is it more normal to run tests via repl or via terminal / CLI ?
REPL
everyone who disagrees is wrong
😄
I come from C# where tests would be automatically run when a file changes
I run tests via my editor (which uses the REPL, of course).
I kinda miss that
Ghadi coming out swinging I like it 😛
😄
I have hot keys bound to “run this namespace’s tests”, “run the current test”, and “run the tests in the associated test namespace” — used when I’m working in a source file, so I don’t have to switch to the test file or anything.
run tests through the editor/repl as you develop, and then at the end of a "session", run the whole test suite from the command line to verify your work
Yup ☝️:skin-tone-2:
only have to do that last step once or twice a day
(but that all may be harder with cljs?)
Yes.
> “run this namespace’s tests” Calva has this but I think this is what emilaasa pointed out not working for cljs as the repl says this:
; Evaluating file: interpreter.cljs
nil
; Running tests for exfn.interpreter...
; No tests found. 😱, ns: 0, vars: 0
cljs꞉exfn.interpreter꞉>
I think you had the right idea @qmstuart with evaluating (run-tests)
.
I'd probably have it as an expression in the file and just run it from there - maybe with marks or something if VSCode supports it
It will pick up anything from deps.edn
if present as well, but it can also be used in a directory without deps.edn
.
As a beginner, you're going to want to focus on avoiding doing the easy, lazy thing: jumping out of your live environment to run your tests from the cli
this takes practice
Or maybe there's some REPL command abstraction that you can bind a keystroke to
(comment
(run-tests)
...)
So you can eval it when you want to, rather than having it run every time you eval the file.
@qmstuart I'm not a calva / vscode user but: https://calva.io/custom-commands/ might work
I think this is key, every time (atleast that I can remember) I've done things the slower more familiar way I've regretted it and it just took longer to learn the right way. 🙂
@seancorfield Maybe it's these guys that make it a bit brittle: https://github.com/clojure/clojure/blob/28efe345d5e995dc152a0286fb0be81443a0d9ac/src/clj/clojure/test.clj#L260
Hm is that even the code btw that you are supposed to run cljs tests with?
you mean I shouldn't be using (deftest) and (run-tests) to write cljs tests?
I have no experience writing cljs at all but I've been surprised before - sec
(ns my-project.tests
(:require [cljs.test :refer-macros [deftest is testing run-tests]]))
Is that how you require it?
I went and read the source for clojure test code 🙂
Instead of cljs.test
But it looks like the same deal
I have this
(ns test.interpreter-tests
(:require [cljs.test :refer [deftest is testing run-tests test-ns]]
[exfn.interpreter :refer [interpret build-symbol-table mov math-func get-parity]]))
yeah, that looks the same
I'm out of my depth - I think you're doing the right thing and it's hopefully some REPL state messing you up before
Seems to be quite a bit more complicated the code in cljs 😄