This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-08
Channels
- # aws-lambda (2)
- # beginners (66)
- # calva (7)
- # cider (1)
- # clj-kondo (1)
- # cljs-dev (4)
- # cljsrn (2)
- # clojure (79)
- # clojure-android (1)
- # clojure-spec (8)
- # clojure-sweden (3)
- # clojure-uk (12)
- # clojurescript (6)
- # datomic (18)
- # duct (1)
- # emacs (31)
- # fulcro (8)
- # hoplon (5)
- # joker (4)
- # luminus (9)
- # off-topic (7)
- # reagent (6)
- # rewrite-clj (8)
- # shadow-cljs (9)
- # spacemacs (42)
- # tools-deps (9)
- # yada (4)
how do I call a non-main static clojure method from the CLI?
code:
(ns clj.core
(:gen-class
:methods [^:static [handler [String com.amazonaws.services.lambda.runtime.Context] String]]))
(defn -main [& args]
(println "Hello, World!"))
(defn -handler [s]
(str "Hello " s "!"))
# java -cp target/clj.jar clojure.main -m clj.core
Hello, World!
# java -cp target/clj.jar clojure.main -m clj.core.handler
Exception in thread "main" java.io.FileNotFoundException: Could not locate clj/core/handler__init.class, clj/core/handler.clj or clj/core/handler.cljc on classpath.
at clojure.lang.RT.load(RT.java:466)
at clojure.lang.RT.load(RT.java:428)
at clojure.core$load$fn__6824.invoke(core.clj:6126)
at clojure.core$load.invokeStatic(core.clj:6125)
at clojure.core$load.doInvoke(core.clj:6109)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5908)
at clojure.core$load_one.invoke(core.clj:5903)
at clojure.core$load_lib$fn__6765.invoke(core.clj:5948)
at clojure.core$load_lib.invokeStatic(core.clj:5947)
at clojure.core$load_lib.doInvoke(core.clj:5928)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$load_libs.invokeStatic(core.clj:5985)
at clojure.core$load_libs.doInvoke(core.clj:5969)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$require.invokeStatic(core.clj:6007)
at clojure.main$main_opt.invokeStatic(main.clj:491)
at clojure.main$main_opt.invoke(main.clj:487)
at clojure.main$main.invokeStatic(main.clj:598)
at clojure.main$main.doInvoke(main.clj:561)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:37)
I believe you can call the -main function of any namespace you want with the "-m" or "--main" command line option, but not any other function.
If that is true, you are of course free to write a -main
function that takes additional command line options, such as the name of a method to invoke, or some custom-to-your-application options or names that you write code to determine which method to call.
I'm mostly trying to debug my problem trying to find the right handler for my aws lambda to execute in my uberjar
You can write code in your -main
that takes a string from the command line and uses Java reflection APIs to look up a method by that name, and then call it. Not sure if that would help.
At work, we have a
namespace with a -main
that takes the first argument as a fully-qualified function name and calls it.
So we do java -cp my/uber.jar clojure.main -m
And that will require ws.task
and then resolve ws.task/my-func
and call it.
(since we're on 1.10+, we just use (requiring-resolve 'ws.task/my-func)
You can combine ^^ with -e
True. For the simple CLI case that would work. Our jobs function does component creation / startup and logging too.
hey all happy to be here
I'm tech lead for the content platform at The Economist in London and have just started diving into Clojure
Ooh, as an avid reader of every issue, I am delighted to hear this!
Probably not for work unfortunately
Hey there. I'm in the middle of a clojure project I will turn in for a hiring process, and am enjoying working with it so far. Quite challenging though!
Question: how long should namespace files be? And the separation between them must be by responsibilities? I'm trying really hard not to apply OO into it, so as of right now I have a logic file with over 150 lines. Is that acceptable?
Namespaces can get pretty long, and it's not a problem if they do. Though it helps to seperate the namespace in sections using comment as headers
You don't separate them by responsibility in the same way you would an OO class. In that, it's not single responsibility principle
Just for the purpose of readability mostly. And sometimes to avoid name clashes with other namespaces.
I tend to have one per component. If you are familiar with UML Component Diagrams, namespaces map pretty well with those.
Does that mean every aspect of it? Right now I am working on a REST api for a "board game", or similar to that.
Ya, like if a Java package would have had 10 classes all doing different things. That can all be one namsepace
My logic.clj has, at the moment, functions to check if a movement is valid, apply that movement on a matrix structure, calculate new positions after movement, and all that.
Oh ok. So going back to your suggestion about separating them using comments as headers, I could separate them into "validators" and etc?
just want to echo that nothing about what you’re saying sounds outside of the ordinary in clojure land. have had namespaces with hundreds of lines of code, and namespaces with just a few lines of code. it’s more about how you want to organize a sliver of your code for outside consumption
in an ns of mine I’ll usually have a core or few main functions and then keep all the utils specific to those functions in that namespace as well
Ya just something like
;;;; Board logic
(defn bla ...)
...
;;;; Player movement
(defn foo ...
;;;; State Validation
...
yeah that sounds like a fine way of organizing it. for better or for worse – and you’ll see this the more you tinker w clojure – there’s no one way to do things in clojure
means there’s no guidance and frameworks and you have to figure out how you specifically want to glue stuff together, but the flexibility that provides is very freeing
persistence could have all code to storing states in a db and what not if you need that. And config could for shared globals like credentials, etc.
Hmm interesting. I've been trying to separate things as much as I can due to the OO background.
The big difference is, in OO, the "unit" is the class. But in Clojure, it's the function.
But logic is still with many responsibilities, which seems ok from what you guys are saying. Makes me more confident haha.
So namespaces are just to group somewhat related functions together in a place to easily find it and share them together
Your functions are what will need to be single responsibility, try to have them pure, well factored, composable, etc.
Ya, I wouldn't worry about it. Namespaces with multiple responsibilities is totally normal.
I normally start with one namespace, build almost everything in it, and if I start to feel it is getting hard to find things in it, and the file is too big, I break parts out into their own namespaces. It's purely organizational. Like choosing a folder structure to organize your photos in 😋
You mentioned having gameplay as a namespace. Is logic an acceptable name or is it just placeholder and I should change it?
Ya, logic is fine. I mean, whatever you feel is intuitive for someone looking for what they're looking for 😋
I would just make sure you don't have too many namespaces honestly. For a small program, you wouldn't want to have more then 5, if more then 10 I'd worry you're trying to use them as if they are OO classes
Like company.bagamon.core
and then other namespaces would be like company.bagamon.logic
company.bagamon.utils
, etc. As needed
Oh great tip. I have about 6 now, something like core, service, controller, logic for the flow, and some helpers like matrix (I created a simple namespace with a create, get and set for that) and constants (for globals like size of grid).
@UK73TQZ9P From our code base at work
Clojure build/config 50 files 1019 total loc
Clojure source 279 files 66902 total loc,
3118 fns, 641 of which are private,
422 vars, 29 macros, 60 atoms,
580 specs, 21 function specs.
Clojure tests 308 files 19407 total loc,
4 specs, 1 function specs.
So that's an average of 240 roughly for production code (less for test code -- but we have at least a "stub" test namespace for every source namespace to ensure it loads/compiles without error).A few of our namespaces are as much as 2,000 lines but those are very much outliers.
Just checked, our longest is 2,017 lines. We have just 12 that are 1,000+.
I usually get itchy when namespaces get to around 500 lines