Fork me on GitHub

Hello, how can I solve this?

> (def url "")

> (def file (net.cgrand.enlive-html/html-resource (.URL. url))) 

Syntax error (SunCertPathBuilderException) compiling at (form-init5400902524976976728.clj:499:35).
unable to find valid certification path to requested target


If I recall correctly, lein ships with a helpful routine to download the HTML for a URL and print it in the REPL.


@potetm Hmm, not that I'm aware of... Happy to be proved wrong...


oh wait, it doesn’t matter for his problem anyways


he’s calling the request explicitly, just doesn’t have the certs he needs


but yeah, it was def there at one point. I’d have to track it down.


iirc @noisesmith might have been the one to point it out to me


Cider has an (anti) feature that it will slurp uris automatically. Not sure nrepl in general does though


that’s it, mb


That kinda makes sense. I mean, CIDER has every feature, right? 🙂


Still doesn't solve the OP's problem. I can only assume the cert on that .ni site isn't in the default chain of trust for the JVM?


(I tried that code in a bare clj REPL and got the same exception)


Is there a {:insecure? true} option for html-resource like in clj-http?


it looks like enlive just calls (.getContent) on a URL so no way to get that kind of info there.


@orlandomr27 The certificate of that site seems to be invalid according to openssl too:

openssl s_client -showcerts -connect 
    Verify return code: 21 (unable to verify the first certificate)
I'd say it's best to import the certificate into java keystore manually (also safer then using some kind of "insecure" option forever)

👍 4

(let [body (:body (http/get url {:insecure? true}))
      input (.ByteArrayInputStream. (.getBytes body))]
  (soup/parser input))


where soup/parser is net.cgrand.tagsoup


the html-resource ns has a bunch of methods for retrieving an inputstream. but if you want to get it by other methods this is where you end up anyways

👍 4

Anyone here use Aero? I have a property like this :port #or [#env MONGO_PORT 27018], But when I run in my terminal: MONGO_PORT=27777 And then run in the same terminal: lein with-profile test-profile test The test that checks if the port is 27018 passes. Anyone know why the environment var is not being picked up?

Tzafrir Ben Ami08:03:07

Are you using io/resource to read config file?

Chris O’Donnell12:03:54

If you want an environment variable to be seen by subprocesses you need to set it with export or prepend it to your command. See for more info.

💯 4

@U0DUNNKT2 Beautiful, works as intended now

👍 4
Luis C. Arbildo17:03:39

There a way to write this, without [x times], I mean I don't need the variable x


Is there an idiomatic way to remove elements of a vector using destructuring? Say I have a list of vectors that have 6 elements but I want the data with the 4th and 5th elements removed, how would you approach that?


Well, not necessarily using destructuring, I just approached it that way at first because it would have been very nice and easy. haha. Something like (map (fn [[a b c _ _ f]] [a b c f]) coll)


(let [v [1 2 3 4 5 6]]
  (into (subvec v 0 3) (subvec v 5)))


If the indices are arbitrary, you can also use keep-indexed.


awesome! Thanks folks


Something like,

(keep-indexed #(when (#{0 2 4} %1) %2) [1 2 3 4 5])
;; => (1 3 5)
But your solution using destructuring is elegant. If you really need a vector, pass through (into [] ...).


That said, vectors are not designed for this use case. They aren't efficient for it. Subvec with into is the fastest way


But if you plan on removing a lot of elements, consider using a map instead


Also, vectors can't really have their elements removed. You need to construct a new vector which contains all the other elements.


subvec is fastest because it won't actually copy it all, it'll share the same vector as long as it can under the hood

👍 4

Whereas a solution where you iterate over the whole vector to do so won't


Nice! One more magic.


I did not know that about subvec.


------------------------- cljs.core/subvec ([v start] [v start end]) Returns a persistent vector of the items in vector from start (inclusive) to end (exclusive). If end is not supplied, defaults to (count vector). This operation is O(1) and very fast, as the resulting vector shares structure with the original and no trimming is done.


But when you concat two or more subvecs, it does get copied, right? Or are there more magic?


You can iterate through elements of a vector v2, and conj each of them successively onto a vector v1, unit eventually all of them are, to concatenate, but that takes linear time (times some logarithmic factor) in the size of v2 to concatenate, and is essentially what (into v1 v2) does (except it uses transients for better efficiency in the constant factors involved, although it stiill takes linear time in the size of v2)


The library core.rrb-vector can concatenate two vectors in logarithmic time in the size of the larger one, using a different kind of tree data structure internally than Clojure's built-in vectors use.


It is still a little bit buggy, though, so I wouldn't 100% recommend it unless those remaining bugs are fixed.


Ya, I should have mentioned, while subvec is O(1), the following into is what will slow the operation down, and why using a map or like @U0CMVHBL2 mentioned a more specialized structure built for this split/join use case like rrb-vector would be faster. You can also go down to Java and just use Linked list, but now you are entering mutation land.


Anyways, all these are probably some pre-optimization concerns that don't matter unless you have hot loops or are implementing algorithms.


<@UUGUA0MGQ> If you don't need x, just name it underscore_,_ like `[_ times]`.

👍 8
Luis C. Arbildo17:03:17

yep but is the same, I asked for way for just use times instead [something times]


I don't know of a way, except, (run! println (repeat times "Hello World")) but this will create a sequence for no reason at all and is more wasteful.

Luis C. Arbildo18:03:25

@UJRDALZA5 I guess that the first method is the most common, well I just had curiosity if there a way to do it, thank you


There isn't


The thing is, any given implementation of this will keep track of a counter


since you need to know when to break out of the loop


So why not expose the counter?


In theory dotimes could be made to accept a binding vec that is only a number, but seems a bit silly, saves you one character to type


(defmacro dotimes
 [bindings & body]
 (if (= 1 (count bindings))
  `(clojure.core/dotimes [_# ~(first bindings)]
  `(clojure.core/dotimes ~bindings ~@body)))      

👍 4

When I run lein repl I get an exception saying it can’t find a class of mine. The class it’s complaining about is one where I use :gen-class to subclass InputStream. If I compile the class explicitly in the repl, it works but I can’t figure out why it’s missing to start with.


this tells lein to pre-compile the namespace


Very nice. That’s what I was looking for. Thanks!


The caveat being, you need to run compile again or restart the REPL if the file changes

👍 4

you can try something like if this becomes a hassle