2010-12-30 15 views
13

Niedawno zacząłem z clojure i używam leiningen do stworzenia małego projektu. Mam problemy z uzyskiwaniem leiningen do zachowywania się z argumentami wiersza poleceń. Poniżej znajduje mój src/project/core.cljargumenty linii poleceń z leiningen

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

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

i mój 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"]]) 

Teraz gdy uruchamiam lein run arg1 arg2, to daje mi ten błąd:

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 

Jednakże, jeśli zrobię lein uberjar a następnie do java -jar project-1.0.0-SNAPSHOT-standalone.jar arg1 arg2, otrzymuję prawidłowy wynik.

arg1arg2 

Niezbyt wygodnie jest tworzyć uberjar, aby uruchomić go za każdym razem podczas rozwoju, czy jest lepszy sposób?

+0

try lein uruchom project.core arg1 arg2 – PheliX

+0

@PheliX, tak, który dał trochę prowadzić, daje 'class project.corearg1arg2', ale uberjar daje' arg1arg2 '... wygląda jak jakiś postęp, ale nie całkiem jeszcze do wykorzystania. To, albo brakuje mi czegoś –

Odpowiedz

6

Wygląda na to, że jest spowodowany przez błąd, który został naprawiony w git. Poprawka będzie w wersji 1.4.2, która powinna wyjść za kilka dni. W międzyczasie możesz użyć obejść omawianych tutaj: http://groups.google.com/group/clojure/msg/a8160b23a5019a12

+0

Tak, to działa. użycie '-m' do określenia modułu do uruchomienia sprawia, że ​​działa on idealnie. Wielkie dzięki. –

+0

FWIW poprawka została wydana kilka dni temu. – technomancy

6

Od lein-run: "args zostaną przekazane jako * command-line-args *"

więc trzeba będzie użyć tych. Przykład na stronie pokazuje, jak. Jeśli teraz, jakie argumenty przekazujesz, użyj również: run-alias, aby określić te w twoim projekcie.clj. Ponownie wspomniana strona zawiera wszystkie informacje.

Moja próbka 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"]]) 

a kod testowy:

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

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

Zarówno "run Lein adresowa foo" AS "Lein uberjar" praca dla mnie.

+0

Nie, jeśli usuniemy '(: gen-class)' i części '& args' i wypiszę' * command-line-args * ', otrzymuję' nil' bez argumenty i śledzenie stosu Java z argumentami. I bez klasy genów, uberjar nigdy nie działa –

+0

Weird, właśnie stworzyłem bardzo prosty projekt, który wypisuje tylko * wiersze poleceń-args *, ale nie używam: gen-class i nie mam głównej metoda. Czy rozwiązanie z aliasami run działa dla ciebie? –

+0

Nie masz głównej metody? więc nie używasz leiningen? i nie, definiowanie aliasu startowego z dwoma argumentami i właśnie drukowanie '* wiersza poleceń-argumentów *' nadal daje mi ślad stosu Java. –