Fork me on GitHub
#beginners
<
2018-08-21
>
mfm02:08:21

i want to run--and rollback the changed db-- some function. what i have, that doesn't work, is below:

(clojure.java.jdbc/with-db-transaction [db-spec' db-spec] ;; create a separate db-spec
  (with-redefs [db-spec' db-spec]
    (sync-feed)) ;; inside this, there are jdbc/insert!'s
  (throw (Exception. "sql-test-exception"))) ;; want to rollback
inside (sync-feed) i change the db via jdbc. fails with java.lang.RuntimeException: Unable to resolve var: db-spec' in this context

hiredman02:08:51

don't use with-redefs

hiredman02:08:18

^- general #beginners advice

mfm02:08:50

this doesn't work; it changes the db and doesn't rollback:

(clojure.java.jdbc/with-db-transaction [db-spec' db-spec]
                             (sync-feed)
                             (throw (Exception. "sql-test-exception")))

michael.gaare02:08:00

It would be better if sync-feed took the db spec as an argument

hiredman02:08:06

do not def a global connection

mfm02:08:51

sync-feed does several things; the actual calls to jdbc/insert! and update! are nested in other functions still inside sync-feed. this is just for dev-testing purposes.

mfm02:08:37

i do agree that i'm trying to do something that normally wouldn't be standard practice

mfm02:08:04

with respect to advice "do not def a global connection"--this is a production system that was live long before me; i'm trying to--for dev purposes--do a db transaction and roll it back simple_smile

michael.gaare02:08:19

@mfm for that the immediate problem is that you have your bindings in the wrong order in with-redefs. It's (with-redefs [thing-to-redef temporary-new-value] ...)

mfm02:08:29

ah thank you @michael.gaare. working on it. that at least runs. it still doesn't rollback for me....

mfm02:08:08

ah, works! i had a misplaced paren. thanks very much, everybody! i have noted that db-spec should be a param.

iagwanderson04:08:20

Really dumb question 😕 I am trying to add a css file to my hiccup model. How should I prefer the path? The css is under resources/public/css/style.css

veix.q511:08:38

@iagwanderson http://clojure.java.io/resource might be what you are looking for

iagwanderson11:08:13

I solved it using the wrap-resource from ring. @veix.q5 thx

veix.q511:08:21

@iagwanderson hiccup also has: hiccup.page/include-css

jm.moreau13:08:13

Hi everyone 🙂 Is anyone currently working through Clojure for the Brave and the True?

jm.moreau13:08:37

If so, and you want an online study-buddy, message me. 🙂

jm.moreau13:08:48

(I’m working through it now, slowly)

mark.davidson16:08:18

I’m working on brave and true. Just finished Chapter 3. I just joined #braveandtrue

manutter5114:08:02

also check out the #braveandtrue channel

jm.moreau14:08:15

thanks @manutter51 I didn’t realize that existed. 🙂

alexkeyes18:08:20

does anyone here have experience with nomad?

stopachka19:08:17

Hey team, I am trying to wrestle with an interesting bug: - clojure has saved a string, which when printed looks like "foo ?" - but the "?" is actually a weird character. if do (-> x seq last int) -- I get the number 55357 - however, if i inspect the string in repl, copy the output, then paste it back, I get it as the question mark -- int value of 63

hiredman20:08:25

your editor or terminal or whatever is doing it

stopachka20:08:55

Thanks @hiredman -- what I am trying to understand is, what this character is supposed to be. Google searching for codepoint 55357, it seems to say that it does not exist. Trying to load it in javascript shows it as an unknown character too. However, clojure renders it as a normal ?

stopachka20:08:29

perhaps for unknown codepoints, when we print a string from clojure, it gets converted to a normal ?

hiredman20:08:09

clojure writes out the byte, and whatever display system you are u sing is then responsible for rendering it

hiredman20:08:18

and whatever you are using renders it as ?

hiredman20:08:49

and also makes it c&p as ?, instead of rending it as ? and making it c&p as the actual value

stopachka20:08:09

what do you mean by c&p?

hiredman20:08:13

copy and paste

hiredman20:08:25

e.g. I have an xterm that is setup up properly to handle unicode characters, so the poop emoji is rendered in emacs in that xterm as just a weird space

hiredman20:08:52

but I can still in emacs copy and paste that character around, because even though it renders as a weird space, it copy and pastes as the actual value

stopachka20:08:56

So, one thing that makes think is the following: - in our system, we took this string, and sent to to another service (i.e through http) - the other service ended up saving the string a ? - codepoint 63

hiredman20:08:50

you may have a weird encoding

stopachka20:08:04

I am trying to grok what could have happened there. We have sent other unicode characters, which rendered correctly (i.e smiley faces etc)

hiredman20:08:25

or whatever method you used to serialize the data and de-serialize did it

hiredman20:08:49

are you using clojure or clojurescript?

stopachka20:08:58

clojure. Thanks @hiredman -- I'll keep digging

shrimpywu20:08:03

Hi Clojure experts, Anyone know how to populate default content-type response headers for "OPTIONS" requests? in our code we enabled cors with below code

(defn add-cors [route]
  (wrap-cors route :access-control-allow-origin #".*"
                   :access-control-allow-headers ["Content-Type"]
                   :access-control-allow-methods [:head :post :get :options]))
wrap-cors is from ring.middleware.cors but notice that OPTIONS request always missing Content-Type in response header.

gaverhae21:08:04

Assuming this is the library you're using, looking at the code at https://github.com/r0man/ring-cors/blob/master/src/ring/middleware/cors.clj#L165 it looks like there is no hook to customize the headers on the options response with that library

gaverhae21:08:24

That is, if you're going with wrap-cors; there's a lot more flexibility if you call handle-cors yourself as you can supply a custom response-handler

gaverhae21:08:23

As it's a function you can do whatever you want in there instead of the default add-access-control (you'll probably want to still call that at some point, then do additional stuff)

andy.fingerhut22:08:30

@stopachka In memory, JVMs use UTF-16 to encode the characters of Unicode strings. UTF-16 is a variable-length encoding in general, while most Unicode characters are encoded with a single 16-bit character in memory, some are encoded as a pair of 16-bit characters in memory. These 2 16-bit characters are called a high surrogate and a low surrogate, and all of them fall within a particular numeric range. 55357 decimal is one of the values in that range. It would be less surprising to find such a character if there was another one just after it in the same surrogate range. One on its own seems weird. Search for occurrences of "surrogate" on this Wikipedia page if you are curious to read more about them: https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF

andy.fingerhut22:08:10

UTF-8 is more commonly used in wire protocols between systems. It is also a variable-length encoding, but a single Unicode code point can require anywhere from one to (I think) up to 6 8-bit bytes to represent. The Java libraries have methods for encoding in UTF-8 when writing strings to a socket/file/etc., as well as for decoding UTF-8 when reading.

andy.fingerhut22:08:57

As some wild guess, maybe one place where such conversion should be happening, isn't happening, but that generic comment doesn't necessarily help you find out where.

andy.fingerhut22:08:50

And, as a wrinkle on that, I believe starting with JDK 10 there is an additional optimization where if a string contains only characters in the ASCII set, it will now store that string as a sequence of ASCII bytes in memory, without doubling its size to 16 bits per in-memory character. Cool. That change is I believe transparent to anyone using the JVM libraries for strings, which Clojure does.

jpsoares10622:08:24

I need to apply a function to some of the elements of my vector, let's say I have [1 5 10] and I want to apply inc to only the first 2 values. I thought of a possible solution of creating a vector of functions to apply so I could do something like (mapfuncs [inc inc identity] [1 5 10]). But I'm having problems to find or to create a function like mapfuncs.

hiredman22:08:59

map can take multiple collections to map over

noisesmith22:08:57

(map #(%1 %2) fns nums)

mark.davidson23:08:45

Greetings clojurians! I’m working though the REPL namespace guide and it appears that switching to an existing namespace with (ns foo.bar) is the same as (in-ns 'foo.bar) If that’s the case, why switch using in-ns?

hiredman23:08:55

it isn't the same

mark.davidson23:08:59

It seems to me that in-ns carries a risk if the namespace doesn’t exist. I may assume that the ns function will create a new namespace but vars I created in it are restored

mark.davidson23:08:24

How so @hiredman?

noisesmith23:08:11

ns does not create a new ns if it already exists it just switches to it (plus whatever require, import, etc. you specify)

mark.davidson23:08:03

Thanks @noisesmith, that was my observation. Not clear about the value of in-ns since that functionality is duplicated by ns

noisesmith23:08:54

in-ns is called by ns

gaverhae23:08:59

ns is a macro that does a ton of stuff in addition to calling the in-ns function.

gaverhae23:08:33

You're right that for most "normal" use-cases there is no reason to call in-ns, but there is also no strong reason for the core library to hide it.

noisesmith23:08:04

it can be helpful having a function, since macros can't be used as flexibly

gaverhae23:08:34

Having said that I can't find the code for in-ns in clojure.core; I'm starting to doubt whether it is a function

noisesmith23:08:16

eg. I often run a one liner like (doto 'my.ns (require :reload) in-ns test/run-tests), it's easy to find this in my repl history and run it to reload and execute tests

noisesmith23:08:20

you can't do that with ns

noisesmith23:08:51

^ you can do the above with a function, you cannot do it with a macro

noisesmith23:08:11

I think in-ns might be bootstrapped before some of the other stuff that source needs in order to work

gaverhae23:08:35

Yes it looks like it is created by clojure.lang.RT directly

noisesmith23:08:15

ahh, that does explain it

noisesmith23:08:42

oh fun

(ins)user=> (fn? in-ns)
false
(ins)user=> (ifn? in-ns)
true

noisesmith23:08:59

so yeah: tl;dr in-ns is low level

gaverhae23:08:36

But it is a function; when I did not see it in clojure.core for a moment I wondered if it were a special form.

noisesmith23:08:13

it's an instance of IFn which means it's a first class object and you can call it (see also maps, keywords)

noisesmith23:08:20

it's not strictly speaking an Fn

gaverhae23:08:25

Well apparently it's not a fn? function, but it is a normal var with some callable object attached and no macro flag

noisesmith23:08:44

yeah, IFn but not Fn

mark.davidson23:08:10

Thanks folks! I’ve got more than enough helpful information!

shrimpywu23:08:12

Hi Everyone, in my code, i forward all unrecognized route to /public

(undocumented
    (route/resources "/")))
and i would like to set a cache header in the response but i don't see there is API for static resrouce. https://weavejester.github.io/compojure/compojure.route.html is there any other way i can add a custom response header to all my static resource?