This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-17
Channels
- # adventofcode (2)
- # beginners (153)
- # cider (14)
- # clara (9)
- # cljs-dev (8)
- # cljsjs (1)
- # cljsrn (4)
- # clojure (124)
- # clojure-dev (9)
- # clojure-france (18)
- # clojure-greece (22)
- # clojure-italy (11)
- # clojure-nlp (5)
- # clojure-russia (9)
- # clojure-spec (21)
- # clojure-uk (40)
- # clojurescript (82)
- # core-async (12)
- # cursive (3)
- # data-science (2)
- # datomic (225)
- # devcards (8)
- # docs (2)
- # duct (1)
- # emacs (18)
- # figwheel (2)
- # fulcro (117)
- # graphql (13)
- # hoplon (10)
- # jobs (7)
- # jobs-discuss (7)
- # keechma (8)
- # leiningen (4)
- # off-topic (16)
- # om (2)
- # om-next (3)
- # perun (11)
- # precept (4)
- # re-frame (24)
- # reagent (2)
- # remote-jobs (8)
- # ring (2)
- # ring-swagger (9)
- # rum (42)
- # shadow-cljs (8)
- # spacemacs (3)
- # specter (7)
- # uncomplicate (10)
- # unrepl (58)
- # yada (9)
Changing to with-redefs
also doesn't seem to work either
(deftest test-web-auth
(testing "sign-up successful"
(with-redefs [#'project.service.auth/sign-up (fn [cred] mock-created-user)]
(let [request-body {:name "John Doe" :email ""}
response (app (mock/request :post "/signup" sign-up-payload))]
(is (= (:status response) 201))
(is (= (:body response) mock-created-user))))))
@hawari.rahman17 The most likely issue is the way you've defined app
I think -- can you share that part of your code?
What does the #object[o] mean in this output: #js {:NativeTypes #js {:FILE __NATIVE_FILE__, :URL __NATIVE_URL__, :TEXT __NATIVE_TEXT__}, :getEmptyImage #object[n], :default #object[o]}
My best guess is that it is a reader conditional, but I don’t see anything that follows that form.
I don't remember what I did but now the test not only calls the original function, it also throws a ClassCastException
on the with-redefs
line:
java.lang.Boolean cannot be cast to clojure.lang.IFn
@hawari.rahman17 What I think is happening here is that the routes is compiling to the original function before you get a chance to redefine it for the mock. Use #'
on the functions there to compile Var references to provide a level of indirection.
Also, since you're passing the whole request, you can simplify how you declare the routes as well... (POST "/signup" [] #'auth/signup)
You might also want to use #'app-routes
instead of app-routes
in the definition of app
so that you can update the routes and have those changes take effect without having to stop and restart your entire web app.
Then (with-redefs [project.service.auth/signup (fn [req] ...)] ...)
should work (no #'
here).
So basically the app should looks like this, @seancorfield?
(def app
(-> #'app-routes
#'wrap-exception-handling
wrap-json-response
(wrap-json-body {:keywords? true})
(wrap-defaults api-defaults)))
Yeah, using a Var -- #'
-- means that you can redefine (or mock) the function and the changes will be picked up, because the Var introduces a layer of indirection.
Did you also make the change I suggested in the routes themselves, to use Vars as well?
I did, but do you think we need to change the auth routes as well?
(defn sign-up
[request]
(let [{credential :body} request
result (#'auth/sign-up credential)]
(cond
(contains? result :error) (process-error result)
:else {:status 201 :body result})))
No, not inside that function. Just inside the app-routes
definition
Show us how your defroutes
looks now...
(defroutes app-routes
(POST "/signup" [] (#'auth/sign-up request))
(POST "/signin" request (auth/sign-in request))
...
(route/not-found {:error "Path not found"}))
(POST "/signup" [] #'auth/sign-up)
simplify it
Then I don't know what to suggest. What I'm suggesting works.
can partial
be used with a second or third argument, but without the first?
Does with-redefs
expect a var or a symbol @seancorfield?
@michael740 No, partial
sets things up so the last arguments can be omitted. You need an anonymous function to omit other arguments.
Symbols -- as I indicated above.
@seancorfield the purpose of that anonymous function would be to rearrange the arguments?
@michael740 Yes, #(some-fn % other args)
thank you!
@michael740 At work we have a flip
function modeled after Haskell that allows us to omit the first argument since it's fairly common: (flip some-fn other args)
i like seeing if haskell has these functions, too. gives me a sense of whether a given function or technique is proper to functional programming or lisps
@seancorfield, you're going to kill me for this, I was testing from inside my emacs, with cider already jacked in. It seems that it doesn't reload my code properly. After running the test with lein test
it works now.
@hawari.rahman17 No problem. Glad you got it working! It's hard to debug people's code remotely 🙂
@michael740 Yeah. It's also interesting when an idiom doesn't cross language boundaries -- for example Haskell leans on monads heavily but they're fairly rare in Clojure.
Thank you, I really appreciate your help @seancorfield
@hawari.rahman17 Sometimes a REPL will get in a bad state, esp. if you're trying to redefine functions so just closing and restarting the REPL can help. I've found, since I switched to Component for everything, that has really helped since I no longer have to restart the REPL as often, just stop & restart the main app component.
The other thing is running both the web app and the tests in the same REPL -- which also can make life a lot easier (although you have to remember that if you do HTTP requests to the app from your tests, they're executing in different threads).
Alright @seancorfield, guess I need to refine my workflow then
Developing a fluid workflow centered around the REPL is a key part of being productive with Clojure, but it takes time and experimentation, and it really depends on your tools.
I highly recommend Stu Halloway's talk on REPL-Driven Development that he gave to the Chicago Clojure group in mid-2017.
@seancorfield thank's for the talk
Just a crazy idea, do you think it would be possible to debug someone remotely with nrepl ?
that would me a major improvement compared to our current workflow with pastebin and stack overflow
Link to that talk to save folks using Bing/Google: https://vimeo.com/channels/1116889/223309989
@fmind It's definitely possible, but screen sharing (via any number of services) is probably easier than trying to do it all via a REPL.
I no longer use nREPL -- I use Atom/ProtoREPL locally which doesn't rely on nREPL and in our apps we use Socket REPLs if we need them.
@seancorfield indeed, it seems more practical. I'm always intrigued by the workflow that could be developed with dynamic languages
like recently, with the release of dynadoc https://github.com/oakes/Dynadoc
I have this impression that toolings for dynamic languages have not been explored to their full potential
Yup, agreed. We have over a dozen separate web apps and it's easy to fire up a REPL, keep it open for days, and stop/start any number of the web apps, and their test suites, and work interactively, evaluating code as you write it, running a test -- or all tests in a namespace -- easily and repeatedly, evolving your code and tests as you go.
That is the first time I've watched one of Zach's videos -- he's hilarious! Love that video!
I wanna run integration test within one connection, and wrap each test in transaction. https://github.com/pn-y/hsp/blob/master/test/clj/hsp/application_test.clj#L7 It was not so hard to do it within unit tests, but with fully started app i'm totally lost. How could i inject connection with transaction to already started system? I've tried different ways, but didn't succeed https://github.com/pn-y/hsp/blob/master/test/clj/hsp/test_helpers.clj#L42
@seancorfield check out Zach's conference talks for an informative good laugh
hello everyone, I'm running to an issue where lein uberjar
or lein with-profiles uberjar compile :all
where it just hangs. Is there away to run lein uberjar that prints out more info like --verbose or something?
@joelv any chance you can do a thread dump? jcmd <pid-of-lein-uberjar> Thread.print > td.txt
imperatively, i can use a loop to repeatedly apply a function to, e. g. a list. what's a good functional or stateless alternative?
reduce
?
loop ... recur?
Hi. I'm building one test case and I need to check if one function that runs in background is invoked. Currently I'm doing something like:
(defn do-something-1 [a b c]
;; dosemthing)
(defn do-something-2 [a]
(let [b 1 c 2]
(send-off (agent a) b c)))
And my test case is:
(deftest test-do-something-2
(let [invoked? (promise)]
(with-redefs [do-something-1 (fn [a b c]
(is (= a 3))
(is (= b 1))
(is (= c 2))
(deliver invoked? true))]
(do-something-2 3)
(is (true? (deref invoked? 5 false)))))
It works whether do-something-1
function is invoked in less 5 millisecond.
Who can give me other suggestions?
Thanks!suppose i want to double a number n times. reduce acts on a collection, right?
i think i want loop recur
and pass along the output each iteration
you can use reduce for that, for instance: (defn doubler [start, doubles] (reduce (fn [total i] (* total 2)) start (range doubles)))
is reduce using the (range doubles)
for anything other than a stop condition?
Looking for suggestions on parsing XML with clojure? anything more friendly than https://clojure.github.io/clojure/clojure.xml-api.html ?
have you tried https://github.com/clojure/data.xml ? I’ve used it for a variety of things and have usually found it to be pretty serviceable.
these days I’m using the 0.2.0 alphas
Ok thanks, i'll check it out 🙂
I just wrote up this function, which is handy for some playing-around I'm doing:
(defn map-neighbors
"Applies predicate to every pair of neighbors in the sequence, returning a lazy sequence of the results."
[pred s]
(map-indexed
#(pred (nth s %1) %2)
(rest s)))
E.g.:
app.core> my-p
;; => [2 4 6 8 5 3 4]
app.core> (map-neighbors list my-p)
;; => ((2 4) (4 6) (6 8) (8 5) (5 3) (3 4))
app.core>
I was unable to find something like this already in existence. Is there an easier/better way?(map pred s (rest s))
also pred
is an odd name here, f
would be idiomatic
pred is specifically for things that return true or false
(I still tend to look for functions, rather than ways to apply existing functions in flexible ways, to solve problems in Clojure...presumably that's a tendency among many who, like I, have decades of experience writing in imperative languages when learning functional programming?)
@james-clojure Yes, I think so. It takes a while to get into the mindset of thinking about problems as a composition of small functions.
yes - I found that the exercises at http://4clojure.com (and looking at the answers from more experienced users) helped me get a better grasp of how to use clojure’s built in stuff
☝️:skin-tone-2: Definitely good advice! 4clojure was extremely valuable when I was learning. Haven't looked at it in years now so I tend to forget...
one of these weekends I’ll hit 100% of the exercises there heh
Hahaha... I got to 100% and kept on top of that in the early days... I don't know that I'd ever find the time to get back to 100% now 🙂
4clojure is on the order of individual functions, whereas AOC is solving more complex problems
I get the impression that 4clojure is much more streamlined for using clojure
@andrew354 for advanced problems it is closer to AOC stuff - graph theory and such
the elementary stuff does focus basic builtins though
the last one I solved was calculating edit distance of strings
AOC has a more "practical" feel too, where some realish business problem is described and you are free to approach it as you like
my sense is that AoC is implicitly geared towards imperative programming
would be curious to know if anyone else thinks so too
why can't i map
Integer.
against a list?
(Integer. "10")
works fine
seems it's not quite a function?
from what i've heard its a method and methods are not first class objects on the jvm
would you recommend read-string
instead?
no, read-string is way too powerful for this
among other issues, read-string allows executing arbitrary code
=> (read-string "#=(+ 1 1)")
2
but even clojure.edn/read-string
(which doesn’t have that issue) is still much more general than you need. If you know you want an Integer from a string, use Integer/parseInt, if the input could be anything that the Integer constructor accepts, use (Integer. foo)
also seriously consider using Long rather than Integer in general - the same methods are there, but almost everywhere clojure prefers Longs
Should probably use #(Integer/valueOf %)
, which will cache values rather than forcing new memory allocation
thanks!
i was seeing a lot of different answers on SO
@freneta the caching isn’t from valueOf, it’s part of the implementation of Long / Integer themselves in the vm
=> (identical? (Long/valueOf "1000") (Long/valueOf "1000"))
false
oh wait I see what you mean, by using the constructor you bypass that caching
> This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
right, valueOf and parseInt / parseLong each use that cache
also you can mutate values in that cache via reflection and cause really crazymaking bugs haha
I would've eventually hit that issue with trying to treat Integer.
as first class, so thanks @michael740 for making me figure it out ahead of time. 🙂
I'm following along some code someone else has written (clojurescript) and I noticed that they seem to be using !
at the end of some of their definitions: (declare action!)
, (defn register-component! ... )
Is this a common convention and does it mean something? I can't seem to find docs for it. 😕
Some people use a trailing bang to indicate a fn with side effects. Others use it to indicate a fn that may throw exceptions you want to handle, though that’s less common I think.
Ah, thank you good to know. I'm still at the stage of trying to parse actual syntax from convention I'm afraid. -_-
clojure has no suffix syntaxes, and very few prefix syntaxes
most prefixes are #
followed by something, except @
, '
, ` (and of course I forgot a few others but they are all in the “weird characters” link)
As far as naming your own functions, a pattern that has stuck pretty well ( I think ) is to name side-affecting functions with a bang (!) at the end, binary functions (true or false) with a question mark (?) at the end, and functions that might throw an error with a double bang (!!) suffix. This is by no means a community standard though, just what made/makes sense to me
Thanks again @noisesmith and @admay I actually found some guidelines for the !
pattern in that documentation: https://clojure.org/guides/weird_characters#__code_symbol_code_unsafe_operations 🙂
Isn't #
a significant suffix to designate gensym's within macro bodies? I've actually used it (after seeing other code use it), but hadn't remembered it from reading "The Joy of Clojure" last summer/fall....
yeah, I forgot that one (sub-syntax of `)
very beginner question for spec
(s/def ::title string?)
(s/def ::title-info (s/keys :req-un [::title]))
(s/def ::rows (s/coll-of ::title-info))
wanting to spec [{:title "title"} {:title "another-title"}]
this works:
(s/conform (s/coll-of ::title-info) [{:title "bob"}])
[{:title "bob"}]
but not
(s/conform ::rows [{:title "bob"}])
:cljs.spec.alpha/invalid
anyone use cider // clojure layer spacemacs? what's a good way to wipe my repl clean and restart it?
@michael740 ,
will bring up a menu in the repl. there's refresh and restart
found it!
@dpsutton that works in Clojure and should also work in ClojureScript if it doesn’t
(also, fyi there is #clojure-spec which I watch more closely than here)
totally fine there