2014-05-18 15 views
8

Właśnie rozpoczęła się na moim pierwszym projekcie Clojure użyciu Lein, kod tutaj:Clojure: Lein uruchomić stanie rozwiązać symbol

(ns fileops.core 
    (:use 
    [clojure.core :only (slurp)] 
    [clojure-csv.core :only (parse-csv)] 
    [fileops.core])) 

(defn -main 
    "I don't do a whole lot ... yet." 
    [& args] 
    (read-file "sample.csv")) 

(defn read-file 
    "open and read the csv file" 
    [fname] 
    (with-open [file (clojure.java.io/reader fname)] 
    (parse-csv (slurp fname)))) 

próbowałem uruchomić to przy użyciu "run Lein" ale wciąż otrzymuję ten błąd:

Caused by: java.lang.RuntimeException: Unable to resolve symbol: read-file in this context 
    at clojure.lang.Util.runtimeException(Util.java:219) 
    at clojure.lang.Compiler.resolveIn(Compiler.java:6874) 
    at clojure.lang.Compiler.resolve(Compiler.java:6818) 
    at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6779) 
    at clojure.lang.Compiler.analyze(Compiler.java:6343) 
    ... 52 more 

Co robię źle?

+4

odczytu plik powinien być przed głównym w źródle. –

+0

@DiegoBasch oszczędzasz życie. Jestem nowy w Clojure i spędziłem zbyt wiele czasu próbując dowiedzieć się, dlaczego dostaję błąd, że moja funkcja została wywołana w niewłaściwym kontekście. To było to ... To było przez cały czas. Wspaniały post. –

Odpowiedz

9

Użyłeś tylko SLURP z rdzeniem Clojure, co oznacza, że ​​co drugi rdzeń funkcja jest obecnie niedostępny dla ciebie :) Spróbuj zmienić ns używać :require zamiast :use, ponieważ jest to bardziej idiomatyczne.

Należy pamiętać, że zamówienie ma znaczenie w clojure, więc jeśli nie zadeklarujesz funkcji na górze pliku, tak jak w C i niektórych innych językach, wcześniejsze funkcje nie będą mogły utworzyć odwołania do nich. To właśnie powodowało twój błąd przed i dlatego lubię definiować moją funkcję -main na dole. To kwestia stylu.

Inną sprawą jest to, że twoja funkcja -main przyjmuje teraz zmienne argumenty i nie używa ich. W Clojure idiomatyczne jest używanie _ w celu odniesienia się do parametru, który nie jest używany. Możesz użyć & _, aby uniknąć komunikatów o błędach, gdy użytkownik przejdzie niepotrzebne argumenty, ale po prostu od razu będę miał funkcję -binową bez parametrów. Dzieje się tak dlatego, że po uruchomieniu programu nic nie musi być dostarczane do głównej, a błędy ułatwiają debugowanie. Dobrze jest wiedzieć, co jest używane i gdzie. Plik sample.csv jest już dostarczony i ma wywoływane read-file, więc program powinien działać, jeśli twoja funkcja read-file jest poprawna, a plik sample.csv znajduje się we właściwej lokalizacji.

Jeśli chodzi o twoją funkcję -main, byłoby miło umieścić tam mały test, aby sprawdzić, czy działa on prawidłowo, więc zmieniłem go, aby wydrukować zawartość pliku CSV na konsolę. Ten sposób drukowania z pliku jest wydajny i warty samodzielnego studiowania.

Na koniec upewnij się, że zawierasz clojure-csv.core w swoim pliku project.clj.

core.clj:

(ns fileops.core 
    (:require 
    [clojure-csv.core :refer [parse-csv]])) 

(defn read-file 
    "open and read the csv file" 
    [fname] 
    (with-open [file (clojure.java.io/reader fname)] 
    (parse-csv (slurp fname)))) 

(defn -main [] 
     (println (clojure.string/join "\n" (read-file "resources/test.csv")))) 

project.clj:

... 

:dependencies [[org.clojure/clojure "1.5.1"] 
       [clojure-csv/clojure-csv "2.0.1"] 
       ...] 
:main fileops.core 

Musisz zadeklarować fileops.core jak: main, jak pokazano powyżej. To mówi Leiningenowi, jaka funkcja ma zostać wykonana po wprowadzeniu lein run. Bardzo ważne i trudne rzeczy.

Teraz upewnij się, że są w głównym katalogu projektu i na terminalu, uruchom następujące:

lein clean 
lein deps 
lein run 

Powodzenia!

Dalsze czytanie:

8th light blog on name-spaces

flying machine studios explanation of lein run

+1

To jest moja pierwsza zaakceptowana odpowiedź na SO. Wielkie dzięki! :) – kurofune

Powiązane problemy