2010-12-30 8 views
13

Ich habe vor kurzem mit Clojure begonnen, und ich benutze Leiningen, um ein kleines Projekt zu erstellen. Ich habe Probleme damit, sich mit Befehlszeilenargumenten zu verhalten. Im Folgenden ist mein src/project/core.cljKommandozeilenargumente mit Leiningen

(ns project.core 
    (:gen-class)) 

(defn -main [& args] 
    (println (apply str args))) 

und meine project.clj

(defproject project "1.0.0-SNAPSHOT" 
    :description "FIXME: write" 
    :main project.core 
    :dependencies [[org.clojure/clojure "1.2.0"] 
       [org.clojure/clojure-contrib "1.2.0"]]) 

Wenn ich jetzt lein run arg1 arg2 laufen, es gibt mir diese Fehlermeldung:

Exception in thread "main" java.lang.Exception: Unable to resolve symbol: arg1 in this context (NO_SOURCE_FILE:1) 
    at clojure.lang.Compiler.analyze(Compiler.java:5205) 
    at clojure.lang.Compiler.analyze(Compiler.java:5151) 
    at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3057) 
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5371) 
    at clojure.lang.Compiler.analyze(Compiler.java:5190) 
    at clojure.lang.Compiler.analyze(Compiler.java:5151) 
    at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:4670) 
    at clojure.lang.Compiler$FnMethod.parse(Compiler.java:4328) 
    at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3173) 
    at clojure.lang.Compiler.analyzeSeq(Compiler.java:5367) 
    at clojure.lang.Compiler.analyze(Compiler.java:5190) 
    at clojure.lang.Compiler.eval(Compiler.java:5421) 
    at clojure.lang.Compiler.eval(Compiler.java:5415) 
    at clojure.lang.Compiler.eval(Compiler.java:5391) 
    at clojure.core$eval.invoke(core.clj:2382) 
    at clojure.main$eval_opt.invoke(main.clj:235) 
    at clojure.main$initialize.invoke(main.clj:254) 
    at clojure.main$null_opt.invoke(main.clj:279) 
    at clojure.main$main.doInvoke(main.clj:354) 
    at clojure.lang.RestFn.invoke(RestFn.java:422) 
    at clojure.lang.Var.invoke(Var.java:369) 
    at clojure.lang.AFn.applyToHelper(AFn.java:165) 
    at clojure.lang.Var.applyTo(Var.java:482) 
    at clojure.main.main(main.java:37) 
Caused by: java.lang.Exception: Unable to resolve symbol: arg1 in this context 
    at clojure.lang.Compiler.resolveIn(Compiler.java:5677) 
    at clojure.lang.Compiler.resolve(Compiler.java:5621) 
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:5584) 
    at clojure.lang.Compiler.analyze(Compiler.java:5172) 
    ... 23 more 

Wenn ich jedoch eine lein uberjar tun und dann do java -jar project-1.0.0-SNAPSHOT-standalone.jar arg1 arg2, bekomme ich die richtige Ausgabe.

arg1arg2 

Es ist nicht sehr angenehm zu haben uberjar zu schaffen es jedes Mal zu laufen, während der Entwicklung, gibt es einen besseren Weg?

+0

versuchen lein Lauf project.core arg1 arg2 – PheliX

+0

@PheliX, yep, dass einige Blei gab, gibt es 'Klasse project.corearg1arg2', aber die uberjar gibt's arg1arg2 '... sieht aus wie ein Fortschritt, aber noch nicht ganz brauchbar. Das, oder ich vermisse etwas. –

Antwort

6

Dies sieht so aus, als ob es durch einen Fehler verursacht wurde, der in Git behoben wurde. Das Update wird in 1.4.2 sein, das in ein paar Tagen aus sein sollte. In der Zwischenzeit können Sie Abhilfen hier besprochen verwenden: http://groups.google.com/group/clojure/msg/a8160b23a5019a12

+0

Ja, das klappt. Verwenden Sie "-m", um das auszuführende Modul anzugeben, damit es perfekt funktioniert. Danke vielmals. –

+0

FWIW das Update wurde vor ein paar Tagen veröffentlicht. – technomancy

6

Von lein-run:

So "Args auf als * Kommandozeilen-args * übergeben werden" werden Sie diejenigen verwenden. Das Beispiel auf der Seite zeigt wie. Wenn Sie nun welche Argumente Sie übergeben, verwenden Sie auch: run-aliases, um diese in Ihrer project.clj anzugeben. Auch hier hat die erwähnte Seite alle Informationen.

Meine Probe project.clj

(defproject addressbook "1.0.0-SNAPSHOT" 
    :description "FIXME: write" 
    :main addressbook.core 
    :run-aliases {:addressbook [addressbook.core -main "arg1"]} 
    :dependencies [[org.clojure/clojure "1.2.0"] 
       [org.clojure/clojure-contrib "1.2.0"]] 
    :dev-dependencies [[lein-run "1.0.0"]]) 

Und den Testcode:

(ns addressbook.core 
    (:gen-class)) 

(defn -main [& [args]] 
    (if args (println args))) 

Both "lein run Adressbuchs foo" als "lein uberjar" für mich zu arbeiten.

+0

Nein, wenn ich '(: gen-class)' und die '& args' Teile entferne und '* command-line-args *' drucke, bekomme ich 'nil' mit nein Argumente und eine Java-Stack-Trace mit Argumenten. Und ohne die gen-Klasse funktioniert das Uberjar nie –

+0

Seltsam, ich habe gerade ein sehr einfaches Projekt erstellt, das nur die * Befehlszeilenargumente * druckt, aber ich benutze nicht: Gen-Klasse und habe kein Haupt Methode. Funktioniert die Lösung mit den Run-Aliasen für Sie? –

+0

Sie haben keine Hauptmethode? also verwendest du kein leiningen? und nein, einen run-alias mit zwei Argumenten zu definieren und nur die '* command-line-args *' zu drucken, gibt mir immer noch einen java stack trace. –