detecting running as script

423 views
Skip to first unread message

Mark Volkmann

unread,
Jan 2, 2009, 11:34:53 AM1/2/09
to clo...@googlegroups.com
I have a file of Clojure code that I'd like to experiment with in the
REPL. I use (load file-path) to do that and then I can try out the
functions it defines. At the bottom of the file it calls the functions
required to run my application. Is there a way I can write the code so
it only runs my application when I run it outside the REPL?

For example, this should run the application:

clj myapp.clj

and this should not:

clj
user=> (load-file "myapp.clj")

Ruby has something like this. You surround the code that runs the app like this:

if $PROGRAM_NAME == __FILE__
# code to run application goes here
end

--
R. Mark Volkmann
Object Computing, Inc.

Timothy Pratley

unread,
Jan 2, 2009, 5:20:21 PM1/2/09
to Clojure
I suspect that *command-line-arguments* would have "myapp.clj" as the
0th element in the
clj myapp.clj
Can't test right now though sorry.

Mark Volkmann

unread,
Jan 2, 2009, 5:43:57 PM1/2/09
to clo...@googlegroups.com
On Fri, Jan 2, 2009 at 4:20 PM, Timothy Pratley
<timothy...@gmail.com> wrote:
>
> I suspect that *command-line-arguments* would have "myapp.clj" as the
> 0th element in the
> clj myapp.clj
> Can't test right now though sorry.

Good idea! Unfortunately it seems that *command-line-args* is nil
regardless of whether I load the code in a REPL or run it as a script.
It doesn't include the name of the script, just arguments that follow
it.

Timothy Pratley

unread,
Jan 3, 2009, 12:12:22 AM1/3/09
to Clojure
Ah, another left field idea:
if you test the namespace you will find running from REPL the
namespace will be user
running from the command will be clojure.core
I'm certain that will work as I've tested it in the past.
Bit of a hack, but should do the job.

Meikel Brandmeyer

unread,
Jan 3, 2009, 4:48:16 AM1/3/09
to clo...@googlegroups.com
Hi,

Am 02.01.2009 um 17:34 schrieb Mark Volkmann:

> For example, this should run the application:
>
> clj myapp.clj
>
> and this should not:
>
> clj
> user=> (load-file "myapp.clj")

You should probably pack everything in a namespace
with a main function.

(ns my.app)

...

(defn main
[& args]
...)

Then you can run the script via:
java -cp <appropriate classpath here> clojure.main my.app

Our you can load the file via load-file or require, without
running it.

Downside: the file must be named according to the
namespace rules.

Sincerely
Meikel

Meikel Brandmeyer

unread,
Jan 3, 2009, 5:03:49 AM1/3/09
to clo...@googlegroups.com
Hi,

Am 03.01.2009 um 10:48 schrieb Meikel Brandmeyer:

> Then you can run the script via:
> java -cp <appropriate classpath here> clojure.main my.app

Geez. Too early. You don't need the clojure.main. Just:
java -cp <classpath> my.app

Sincerely
Meikel

Mark Volkmann

unread,
Jan 3, 2009, 1:40:05 PM1/3/09
to clo...@googlegroups.com

Sounds good. I can't find the function that returns the current
namespace though. Do you remember what it is?

.Bill Smith

unread,
Jan 3, 2009, 1:50:03 PM1/3/09
to Clojure
It's in *ns* isn't it?

Bill

On Jan 3, 12:40 pm, "Mark Volkmann" <r.mark.volkm...@gmail.com> wrote:
> On Fri, Jan 2, 2009 at 11:12 PM, Timothy Pratley
>

Mark Volkmann

unread,
Jan 3, 2009, 1:50:33 PM1/3/09
to clo...@googlegroups.com

I just learned that the current namespace is stored in the special
variable *ns*.

It's not clear though that this will help. When I add (println "*ns*
=" *ns*) to the top of my .clj file, I get the same output:

*ns* = #<Namespace user>

whether I run it as a script or use (load-file "demo.clj") from a REPL.

Kyle Hargraves

unread,
Jan 3, 2009, 1:47:03 PM1/3/09
to clo...@googlegroups.com
On Sat, Jan 3, 2009 at 12:40 PM, Mark Volkmann
<r.mark....@gmail.com> wrote:
> Sounds good. I can't find the function that returns the current
> namespace though. Do you remember what it is?

You can get the current namespace from *ns*.

k

Timothy Pratley

unread,
Jan 4, 2009, 4:57:44 AM1/4/09
to Clojure
> I suspect that *command-line-arguments* would have "myapp.clj" as the
> 0th element in the
> clj myapp.clj
> Can't test right now though sorry.

I tested this and it does work for me. If it does not work for you is
most likely in your clj script or bat file. I noticed on the wiki the
incorrect advice was given:
java -cp %CLOJURE_JAR%;%CONTRIB_JAR% clojure.lang.Script %1

I've updated the wiki with the correct usage:
java -cp %CLOJURE_JAR%;%CONTRIB_JAR% clojure.lang.Script %1 -- %*

Check your script for the -- between script name and arglist. Note
that %* includes %1.

script-test.clj:
(if *command-line-args*
(println "SCRIPT")
(println "REPL"))


C:\java>clj script-test.clj
SCRIPT

C:\java>clj
Clojure
user=> (load-file "script-test.clj")
REPL
nil

Timothy Pratley

unread,
Jan 4, 2009, 5:15:26 AM1/4/09
to Clojure
Hi Meikel,

On Jan 3, 9:03 pm, Meikel Brandmeyer <m...@kotka.de> wrote:
> java -cp <classpath> my.app

I can't seem to get this approach working:
I created a directory "my"
and a file "app.clj" containing:
(ns my.app)
(defn somefunc [])
(println "somefunc!" args))
(defn main [& args]
(somefunc))

C:\java>java -cp .;"c:/java/clojure/clojure.jar" my.app
Exception in thread "main" java.lang.NoClassDefFoundError: my/app
Caused by: java.lang.ClassNotFoundException: my.app

http://clojure.org/compilation seems to imply that this approach can
only be taken using :gen-class and pre-compiling before calling in
this way (which makes sense as my.app is not a class yet).


Meikel Brandmeyer

unread,
Jan 4, 2009, 5:21:15 AM1/4/09
to clo...@googlegroups.com
Hi,

Am 04.01.2009 um 11:15 schrieb Timothy Pratley:

> I can't seem to get this approach working:
>

> http://clojure.org/compilation seems to imply that this approach can
> only be taken using :gen-class and pre-compiling before calling in
> this way (which makes sense as my.app is not a class yet).

Yes. I found this out after sending the mail. But still clojure.main
does this somehow....

Sincerely
Meikel


Mark Volkmann

unread,
Jan 4, 2009, 8:58:04 AM1/4/09
to clo...@googlegroups.com

Thanks! I've got it working this way now. My script defines a "main"
function. At the bottom of the script I do this:

; Only run the application automatically if run as a script,
; not if loaded in a REPL with load-file.
(if *command-line-args* (main))

Grunde

unread,
Jan 14, 2009, 5:19:32 AM1/14/09
to Clojure
Hi all,

I managed to make this work by first making a clj script as instructed
here:
http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started
(thanks, great stuff!)

But there is still one small thing:
Is there an elegant way to "unwrap" the passed command line arguments?
And is there any module in Clojure to parse command line arguments
like Ruby and Pythons "optparse"?

My tiny script:
------------------
#! /usr/bin/env clj
(defn somefunc [& args]
(println "somefunc!" args))

(defn main [& args]
(somefunc args))

(when *command-line-args*
(main *command-line-args*))
---------------------

When I run it from the command line I get:

$ ./test.clj this is the command line args
somefunc! (((./test.clj this is the command line args)))
$

Best,
Grunde

Grunde

unread,
Jan 14, 2009, 5:58:58 AM1/14/09
to Clojure
Hi folks,

I'm almost there.

My small script:
------
#! /usr/bin/env clj
(defn somefunc [& args]
(println "somefunc!" args))

(defn main [& args]
(somefunc args))

; Only run the application automatically if run as a script,
; not if loaded in a REPL with load-file.
(when *command-line-args*
(main *command-line-args*))
-------

When I run from the command line I get:

$ ./test.clj parameters here
somefunc! (((./test.clj parameters here)))
$

Now, it these some elegant way to parse and use the passed command
line arguments in my program? Is there any lib like Ruby/Pythons
optparse to assist parsing of command line arguments?

Best,
Grunde



On 4 Jan, 14:58, "Mark Volkmann" <r.mark.volkm...@gmail.com> wrote:

Chouser

unread,
Jan 14, 2009, 12:00:45 PM1/14/09
to clo...@googlegroups.com
On Wed, Jan 14, 2009 at 5:58 AM, Grunde <grunde...@gmail.com> wrote:
>
> Now, it these some elegant way to parse and use the passed command
> line arguments in my program? Is there any lib like Ruby/Pythons
> optparse to assist parsing of command line arguments?

There is clojure.contrib.command-line

I don't know if it's elegant, and it's certainly not (yet) as powerful
as many optparse tools in some other languages, but I've found it to
be useful.

--Chouser

Grunde Løvoll

unread,
Jan 14, 2009, 2:11:23 PM1/14/09
to clo...@googlegroups.com
Thanks!

I'll have a look at clojure.contrib.command-line. I don't need
anything super-powerfull, just something that make it easy to define
and parse command line arguments in the "normal manner".

Sorry about my previous double post :(

Grunde
Message has been deleted

Sean Corfield

unread,
Jun 12, 2018, 3:44:32 PM6/12/18
to clo...@googlegroups.com

I thought this was the go-to library for command line parsing:

 

https://github.com/clojure/tools.cli

 

I believe it is, yes. Some history:

  • I think clojure.contrib.command-line was created by Chris Houser and maintained mostly by Stuart Sierra (until 2011). It was deprecated along with everything else in “Monolithic Contrib” as part of the Clojure 1.3 release.
  • clojure.tools.cli was originally created by Gareth Jones from the Clargon library (starting in 2011)
  • For the 0.3.0 release, Sung Pae took over and rewrote it based on his optparse-clj library and included ClojureScript support (starting in 2013)
  • I took over as maintainer for the 0.3.2 release (starting in 2015) and I’m happy to look at any enhancement requests or features offered by any other command line argument parsing library that folks make me aware of!

 

Sean Corfield -- (970) FOR-SEAN -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood

 


From: clo...@googlegroups.com <clo...@googlegroups.com> on behalf of Patrik Sundberg <patrik....@gmail.com>
Sent: Tuesday, June 12, 2018 6:13:39 AM
To: Clojure
Subject: Re: detecting running as script
 
I thought this was the go-to library for command line parsing:

https://github.com/clojure/tools.cli

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to the Google Groups "Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Patrik Sundberg

unread,
Jun 13, 2018, 6:21:54 PM6/13/18
to Clojure
Yeah - I ended up in this thread from some searching, then got distracted/confused about browser tabs and didn't realize I was dealing with a 9 year old thread :)

Thanks for the history!
Reply all
Reply to author
Forward
0 new messages