Fork me on GitHub
#beginners
<
2017-05-28
>
shaun-mahood04:05:49

@lepistane: I've done similar things by just having a parameter in the rendering code - then if they don't have access you can hide the UI that they can't use. I prefer it to changing CSS. Do you get to design the whole front end but the back end is fixed?

lepistane08:05:33

@shaun-mahood i am doing both but requirement from client is he wants to show info the the user, see comments etc. once he is logged in he can edit comments which are his. i have if in my code. if logged in - include options for frontend not - not included options (they dont exist, arent just hidden) and also i prevented on server side if some hackers shows up so he cant edit comments that are not his or if not logged in

Geoffrey Gaillard10:05:52

@vitruvia Nice implementation of tails ! I found (sequence nil) a little bit unfamiliar, you can replace it with '(), which is the empty list. Also, you don't need to (seq a-seq), as a-seq is already a sequence. seq is useful when you need to transform something to a sequence (seq "foo") ;; => (\f \o \o ). So you could rewrite

(defn tails [a-seq]
  (if (empty? a-seq)
    (cons '() a-seq)
    (cons a-seq (tails (rest a-seq)))))
You might think "If a-seq is nil, then (cons a-seq …) will fail." but the (empty? a-seq) will prevent it, because (empty? nil) ;; => true

Geoffrey Gaillard10:05:09

if you want to have some fun, you can write

(def inits (comp (partial map reverse) reverse tails reverse))
But a loop/recursion-based implementation would be better if you care about performances or stack overflows 😉

noisesmith14:05:13

@ggaillard there is never a reason to use '(), you can just use ()

Geoffrey Gaillard15:05:56

@noisesmith I took the habit to quote list literals to distinguish them from calls, I didn't knew it worked. Thank you !

noisesmith15:05:58

it's unambiguous, so it's a special case () can't possibly be calling anything

shaun-mahood15:05:10

@lepistane: Sounds like a good way to do things to me

nimblerabit18:05:18

Can anyone let me know if this is the right way to do Java interop, I'm getting an error and I'm not sure if it's just my syntax. Original Java:

ChromeOptions options = new ChromeOptions();
options.addArguments("start-maximized");
Clojure Version:
(doto (ChromeOptions.)
  (.addArguments "start-maximized"))

madstap18:05:11

@nimblerabit that is the right way to use doto

nimblerabit18:05:29

Is there any reason I might be getting this error on the code above?:

IllegalArgumentException No matching method found: addArguments for class org.openqa.selenium.chrome.ChromeOptions  clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:80)

lepistane18:05:38

thank you all for being such a wonderful community ❤️

john18:05:07

@nimblerabit What error are you getting?

john18:05:27

looks legit, I think

john18:05:44

oh, there it is

mobileink19:05:26

do you need a type hint?

mobileink19:05:26

what happens if you explicitly type-hint the args? i believe i've come across similar, where adding a type hint helps the compiler figure out what to do.

noisesmith19:05:45

@nimblerabit the first thing to check is if you are doing varargs properly - that's a varargs method

noisesmith19:05:51

what does your call look like?

mobileink19:05:28

not sure tho, it's been a while. but Reflector makes my spidey sense tingle.

noisesmith19:05:18

@mobileink it takes string varargs, type hints won't help there - it knows the class the method is being called on

mobileink19:05:59

ah. needs a vector?

noisesmith19:05:18

the common error here is to see that Foo.bar takes String* so you call it (.bar (Foo.) "a" "b" "c") where actual varargs looks like (.bar (Foo.) (into-array String ["a" "b" "c"]))

noisesmith19:05:26

it needs an array

mobileink19:05:03

been bit in the butt by that before.

noisesmith19:05:55

oh - that method can also take List

noisesmith19:05:22

and a clojure vector is a List, so that's the easier way to do it

mobileink19:05:25

in any case, Clojure can't figure out what to do with the arg, type-wise, so it can't match a method. yeah?

noisesmith19:05:55

the type doesn't match anything defined for the method, and clojure doesn't do very much implicit type coercion to match methods

john19:05:58

Doesn't it also take a String? Or does the ... arguments in java.lang.String... arguments mean that it is still a varargs?

mobileink19:05:02

one of those interop gotchas.

noisesmith19:05:14

pretty much "try Int or int or long if passed a Long"

noisesmith19:05:45

@john it doesn't have a non-optional string arg

noisesmith19:05:54

so it can only take strings via varargs

noisesmith19:05:55

@mobileink java wouldn't really help you coerce arg types to match a method either iirc, I think it's just a vm thing (except varargs, the java compiler is much more friendly about that)

john19:05:10

@noisesmith and it is the ... arguments in the signature that tells you it must take the strings via varargs?

noisesmith19:05:24

Foo... means 0 or more foos, all are varargs

noisesmith19:05:43

you are parsing it wrong, it's String... (named "arguments")

noisesmith19:05:05

the ... parameterizes String

mobileink19:05:48

noisesmith: more precisely: String... means "java arrayof 0 or more strings"?

noisesmith19:05:22

or, even more specifically, a String array (an array of Object wouldn't work, even if it had Strings in it)

noisesmith19:05:40

and an array is always 0 or more items

mobileink19:05:02

noisesmith: hehehehe. java simple made hard. :)

john19:05:10

understood

mobileink19:05:05

one of the first probs i had starting with clojure: calling a java method that takes varargs. into-array did the trick.

mobileink19:05:48
replied to a thread:the ... parameterizes String

noisesmith: more precisely: String... means "java arrayof 0 or more strings"?

nimblerabit19:05:20

Yes, I got it working. Whoever said I needed to put the arguments in a vector was correct, that fixed it.

noisesmith19:05:26

@nimblerabit it takes two types of arg - List (which is matched by a vector) or var strings (which works with into-array)

noisesmith19:05:37

but yeah, the vector is definitely the way to go

nimblerabit19:05:57

So I understand the list one (in fact I had tried using a list myself, didn't realize it needed to be a vector), but I don't get the var strings

nimblerabit19:05:08

How did you know that's what it took, and what does the syntax to do that look like?

noisesmith19:05:13

varargs are implemented on a vm level as an array

noisesmith19:05:31

(into-array Foo [list of foos])

noisesmith19:05:52

Foo being the type that the varargs asks for

nimblerabit19:05:49

This makes sense now, thanks a ton for the help

nimblerabit19:05:06

varargs is extremely confusing to a newbie T_T

noisesmith19:05:04

yes, it is. Have you looked at the http://clojure.org doc page on interop? it's well written

noisesmith19:05:48

oh wow - it doesn't mention arrays for var args - I think it should

nimblerabit20:05:11

Yeah I did read that page, didn't see any var arg stuff there. Luckily you were here! Thanks again for the help

vitruvia20:05:40

@ggaillard Thanks! If I don't use (seq a-seq) the first element of the result becomes a vector, for example (tails [1 2 3 4] becomes ([1 2 3 4] (2 3 4) (3 4) (4) ()). The test cases require that all the results are inside parens.

Geoffrey Gaillard21:05:49

Ah ! Didn't thought about this one! I only tried with quoted lists like (tails '(1 2 3 4)) so I missed it.

vitruvia21:05:27

No problem. Thanks for the help though =]