This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-29
Channels
- # aleph (2)
- # bangalore-clj (1)
- # beginners (9)
- # boot (18)
- # clara (3)
- # cljs-dev (21)
- # cljsjs (2)
- # clojure (137)
- # clojure-spec (2)
- # clojurescript (65)
- # clr (1)
- # copenhagen-clojurians (11)
- # core-async (20)
- # datascript (3)
- # lein-figwheel (1)
- # leiningen (4)
- # luminus (4)
- # lumo (1)
- # off-topic (38)
- # onyx (1)
- # parinfer (4)
- # pedestal (9)
- # protorepl (8)
- # re-frame (4)
- # reagent (92)
- # ring-swagger (2)
- # rum (1)
- # unrepl (40)
- # vim (16)
- # yada (1)
usecase: I want to validate API responses in tests against a schema and have a nice test report if things fail
@hmaurer what I do is call s/check on the schema and the object, and fail if the result isn't nil with the output of check in the failure
@noisesmith how should I configure clojure.test to have a nice output for “expected” and “actual” on the report?
@hmaurer test/is lets you put anything you want in the second arg's string
@hmaurer umm that's kind of what clojure.test does when you run the tests
are you talking about doing this outside unit tests?
Clojure 1.9.0-alpha15
+user=> (require '[clojure.test :as t] '[schema.core :as s])
nil
+user=> (t/is (nil? (s/check [Number] ["a"])) "expected a number")
FAIL in () (NO_SOURCE_FILE:2)
expected a number
expected: (nil? (s/check [Number] ["a"]))
actual: (not (nil? [(not (instance? java.lang.Number "a"))]))
false
if you test a predicate, all you get in the error is that the predicate didn't return the true/false you expected
+user=> (defmacro handle [obj prop fun]
`(.setValue ~(symbol (str (name obj) "/" (name prop))) (fi javafx.event.ActionEvent ~(symbol "event") ~fun)))
#'user/handle
+user=> (macroexpand '(handle a :onAction (fn [x] nil)))
(. a/onAction setValue (user/fi javafx.event.ActionEvent event (fn [x] nil)))
I don't know if it's cider, but something's misbehavingoh - right- macroexpand silently outputs a form that doesn't start with a known macro
even if the thing in it isn't defined
Cider magic introduces ambiguities and special cases about what's been evaluated and what hasn't, it's an easy mistake
and macroexpand doesn't care if the things inside it are known, it just expands known macros and leaves the rest alone
Ok so it expands with C-x e
in the editor, but not in the REPL, which is set to be the same ns. Huh.
C-x e
by default is for calling a keyboard macro inside Emacs, and I think the default binding for expanding a clojure macro is C-c RET
which works for me from the REPL as well
I get the same result as @noisesmith when typing it in the REPL
It simply returns the input for me on the REPL, but works fine when evaluating with C-x e in the editor
it works for me the same way regardless of whether I type it or evaluate the form in a code buffer or in the REPL
I'm not on the latest version however, so perhaps something changed, anyways this should probably belong to #cider
fizzbuzz.core> (macroexpand-1 '(handle a :onAction (fn [x] nil)))
(.setValue a/onAction (fizzbuzz.core/fi javafx.event.ActionEvent event (fn [x] nil)))
@dpsutton no, you don't miss anything. `clojurefx.controllergen> (macroexpand-1 '(handle a :onAction (fn [x] nil))) (handle a :onAction (fn [x] nil)`
Already restarted the REPL now... I guess what one'd expect now.
{:arglists ([obj prop fun]), :line 37, :column 1, :file "/home/zilti/projects/clojurefx/src/clojurefx/clojurefx.clj", :name handle, :ns #namespace[clojurefx.clojurefx], :macro true}
but it works now
e.g. use the record as a way to get an object implementing some functions (the protocol) so you know it follows a certain interface
sounds like a job for deftype or reify
deftype if you need a named class, reify if you don't
I found a better solution to my problem (not involving this scheme) but my question still stands. To give you some context, I have a bunch of entities that have different access patterns. I was thinking of having an Entity
protocol with some functions such as get
, put
, etc (`EntityRepository` might be a better name actually). Then have a record per entity type implementing that protocol, e.g. (defrecord UserRepository [] EntityRepository (get...
the syntax to use reify or deftype there is nearly identical
it wasn’t really meant as a way to allow to polymorphically pass any EntityRepository
and it will behave the same (except the whole "acts like a hash map" part)
(to have a consistent API for accessing entities across the app, even if at the call point I always know what kind of entity I am accessing)
I still don't see why any of these things imply a defrecord instead of deftype or reify
@hmaurer the chart here is useful https://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/
it recommends reify for your case, unless you need a named type for some reason not mentioned yet
it's like deftype but it automatically acts like a hash map (which is a feature you don't need)
deftype implements protocols, so yes you can do it by implementing the right ones
what is a safe way to suppress ALL output from a called function? I tried both wrapping it up with "with-out-str" and redirecting output with bindings like "(binding [out "chuj" err "chuj2"] ", but my called function still outputs tons of shit
@mjo324_56 the code could be using System/out
directly
System/out
is a Java thing, imagine calling into native java code which does some printing
@mjo324_56 edgy kids would run it in a Docker container for complete isolation
@hmaurer I don’t understand how Docker could be related to the problem, or I don’t understand the problem 🙂
he calls a function, which can potentially call some non-clojure code, which can potentially print something, redirecting clojure’s print facilities does not help redirecting all possible output
even clojure code could do directly (.write System/out "something")
bypassing Clojure’s *out*
if this is what is happening, @mjo324_56 would have to capture the output on lower-level in Java land, something like this: https://stackoverflow.com/a/8708357/84283
I could run the function in a separate process and use OS stuff to redirect it's output, this is(besides inefficient and ugly) not so good since my function is changing some global variables
@mjo324_56 the question is who is printing and via what mechanism, is it just clojure code? on the same thread? do you have control over it? I assume it is more complicated and you don’t know exactly.
my function runs in a seperate thread, so i think @darwin 's solution should not be good, since all of system.out is suppressed this way. Thread1 starts thread2 with the function that i want to silence
@darwin i am calling a third library function, that's printing the mess, havent looked deep inside it to know how it prints all the mess
it should just be a logger
if you configure it's logger you can fix it
@noisesmith , yes i could do it, but since i have function mappings and i plan to expand the code, I would prefer to have a generic method to suppress output
i can fix clj-http.client logging today but I will have the same problem when i add some other stuff tommorrow
no, not fix the logging, configure it - that's the proper way to fix logging behavior, is to provide config
there are only so many logging libs out there
(too many, but not arbitrarily many)
anything in the clj ecosystem should be configurable via slf4j
that's what they are for, yes
yeah, I use timbre's slf4j extension to control java logging things in my app
it's annoying, then you get it configured and pretty much never have to touch it again
you set the log level to a less verbose level for the specific package doing the printing
then you just call stuff and if it is from that package the verbosity is lower
i don't like these solutions, people on the web are complaining that the loggers themself spit output
the function is using a logger
the way to make a logger shut up is to configure it properly
OK, have fun
the logging library - the big one - is already pulled in by clj-http
you can fix this with a small text file that tells the logger how to behave - or some other crazy hack if you really prefer that
the timbre solution is better if you are using timbre / need timbre's features, but the logger that clj-http is already pulling can be controlled with a small props file or xml document
a friendly alternative: I’m not friends with xml, I tend to use this: https://github.com/malcolmsparks/clj-logging-config
@noisesmith clj-http uses this logging library, ok i can configure it, i use many different functions calls, maybe one of em uses another logging library which overrides this stuff?! That's why i'd prefer a "hack", a function which simply silences ALL output of a called function
there's too many ways to output for that to work
one of those ways is via a logging library
they run their own thread for logging, often
so you can't intervene except on the level of that lib and it's thread
i also don;t see in the source of which logging library where is used, neither do i understand how to do this, i put a log4j.properties file into the root of the project, thats supposed to turn logging off
that's why i'd prefer a hack to silence it completeley, simply to much shit is there to configure which both takes my time and makes the projhect more complex
I've already given my opinion on all this, my experience with the jvm tells me that a general supression of output is more complex and difficult to implement than the configs to control the logging that your libraries pull in. But it's your project, do it how you like. The ecosystem is not going to make this easy for you.