This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-03-13
Channels
- # announcements (14)
- # babashka (13)
- # beginners (25)
- # biff (7)
- # calva (36)
- # clj-kondo (22)
- # clojure (31)
- # clojure-austin (1)
- # clojure-europe (12)
- # clojure-losangeles (4)
- # clojure-nl (1)
- # clojure-norway (61)
- # clojure-uk (4)
- # clojurescript (3)
- # datomic (24)
- # events (1)
- # humbleui (9)
- # leiningen (9)
- # lsp (30)
- # malli (3)
- # missionary (15)
- # off-topic (5)
- # re-frame (4)
- # reitit (7)
- # releases (2)
- # remote-jobs (4)
- # rewrite-clj (11)
- # ring-swagger (2)
- # sci (6)
- # xtdb (2)
- # yamlscript (3)
Hello can anyone give any advice on using a particular Java Enum in Clojure?
https://poi.apache.org/apidocs/dev/org/apache/poi/sl/usermodel/PictureData.PictureType.html
I want to use PictureData.PictureType.PNG
but can't work out how to "translate" it. I thought it should be PictureType/PNG
but that doesn't seem to work
perhaps PictureData$PictureType/PNG
might work?
I just recently learned this myself, but when the javadocs say "enclosing interface" indicating this is nested class, you need $
as the separator instead of .
.
okay thanks for this. In the end using the full address worked as per @U11BV7MTK. I was able to use PictureData$PictureType/PNG
when importing the Java library like this:
whereas previously I was reading it in just as
Clojure interops with any jvm bytecode, not a Java language construct.
Java gives some nice sugar to make sibling classes, but you think of them as containing classes
So if you import PictureData
, if you think in “java”, you can use PictureData’s child class PictureType and you would think you could reference it as PictureData$PictureType
. But that’s a java-ism and the bytecode is just making another class and using the $
as the indicator
you can import it thought if you like
(import org.apache.poi.sl.usermodel.PictureData$PictureType
org.apache.poi.sl.usermodel.PictureData)
org.apache.poi.sl.usermodel.PictureData
lexer=> [PictureData$PictureType PictureData]
[org.apache.poi.sl.usermodel.PictureData$PictureType
org.apache.poi.sl.usermodel.PictureData]
What is the best practice for requiring a namespace when needing it only for development in a (comment)?
E.g. In my app
namespace I so far had [integrant.repl.state :as repl-state]
in my :require
in order to have
(comment
(def client (-> repl-state/system ::system/client))
...)
in the bottom of the file, and while I do have integrant/repl
in my :dev
alias I don't have it in my main aliases list, thus resulting in uberjar builds failing
What is the proper way to go about this? Should I remove the [integrant.repl.state :as repl-state]
from the app
namespace :require
and add a (:require [integrant.repl.state :as repl-state])
inside the comment? Is there a better way to do this?Its pretty common for clojure project to have a separate dev file/directory (which you would include with :extra-paths
in your :dev
alias), where you can have your utility/test functions/calls
Yeah I also have that, but I want to have a (comment) with relevant shortcuts in each file / namespace I work on
Are you sure it's that comment
that's the issue?
It cannot be repl-state/system
since the symbol is discarded by the comment
form and thus isn't resolved.
It might be because you have some ::repl-state/...
keyword in there. But those you can fix by either using a full ns or by using :as-alias
in the :require
form as it doesn't require for that ns to actually exist.
I do that a lot. Not sure if it could call it best practice, but it works for me.
(comment
(do
(require '[integrant.repl.state])
(let [datomic (:services/datomic integrant.repl.state/system)
...]
...
)
)
Yeah the issue is not the comment per-se but the require I have in the top of the file:
(ns com.example.app
(:require
[clojure.string :as str]
[clojure.tools.logging :as log]
[integrant.repl.state :as repl-state]
...
...
...
(comment
(def client (-> repl-state/system ::system/client))
...
With integrant.repl.state
required in the dev namespace, I just use the fully qualified name in comments, no need to require.
Ah. Well, don't have that vector in there then. :)
Either do what wevrem does and use require
or use requiring-resolve
.
What magnars suggests will also work, but only if the dev
namespace is already loaded and you're sure you'll remember that it needs to be loaded prior to running code in that comment block.
@U07FCNURX how do you tackle the clojure-lsp warning about the unresolved namespace then?
With
(ns user (:require [integrant.repl.state]))
in dev/user.clj
, you won't even have to remember.@U03PYN9FG77 Add this to .clj-kondo/config.edn
:
{:linters {:unresolved-namespace {:exclude [integrant.repl.state]}}}
@U07FCNURX Heh, you will most definitely remember, only from a completely different perspective, when you're bitten by that autoloading user
namespace. :) The fact that it hasn't happen to you yet doesn't mean that it'll always be the case or that it won't happen to someone else.
The advice not to use user
is common and for good reasons.
For your own code, for sure. I wouldn't be worried about loading very stable external dependencies like integrant that way tho.
Oh. Wait. I just realized that I don’t have any unresolved namespace issues with Integrant repl. Why is that? I only use that ignore macro on the frontend CLJS code like this:
(comment
#_{:clj-kondo/ignore [:unresolved-namespace]}
(-> @re-frame.db/app-db ::rules))
But then I went and looked in .clj-kondo/config.edn
and found this awesome nugget :config-in-comment
, which I’m sure someone on here suggested:
{:lint-as {byt.utils.macros/doall-for clojure.core/for
org.httpkit.client/defreq clojure.core/def
reagent.core/with-let clojure.core/let}
:config-in-comment {:linters {:duplicate-require {:level :off}
:unused-binding {:level :off}}}}
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@U07FCNURX It raises the probability of failure for any kind of code.
It's trivial to have user
unexpectedly become a part of your uberjar and then get surprised_pikachu.jpg
'ed when you remove who-knows-what-it's-for.jar
from your uberjar and the code stops working, only to later on learn that Integrant REPL was a transitive dependency of that jar.
IMO just that cognitive load of "`user` is loaded implicitly, so I have to juggle the classpath and be careful" is not worth it.
That sounds like experience talking, so yeah, a valid concern. I generally no longer create uberjars, and certainly not with my dev
folder in it, but I can see that my habits are not everyone else's habits, and that the "here be dragons"-signs are there for a reason. 🙂
Not my direct experience but I remember at least three instances when that very same thing happened to someone on this server. :) I've had my own share of other issues with uberjars as well, so I don't use them either.
One pattern that helps is having short helper defns in dev.clj (or less preferably, user.clj) with commonly needed objects
e.g. defn db
for returning a db conn
Then, in a comment
, I can (dev/db)
which needs no require and is pleasant to type
A handy kondo config setting for that sort of usage would be:
:config-in-comment {:linters {:unresolved-var {:level :off}
:unresolved-namespace {:level :off}}}