2011-01-05 14 views
3

In meinem Haupt-Namespace habe ich eine Top-Level-Variable mit dem Namen "settings", die als leeres {} initialisiert wird.Zugriff auf vars aus einem anderen Clojure-Namespace?

Mein -main fn legt den Inhalt der Einstellungen mit def und conj basierend auf einigen Befehlszeilenargumente fest (verschiedene Datenbankhosts für Produktion/Entwicklung usw.).

Ich versuche auf den Inhalt dieser Karte von einem anderen Namespace zuzugreifen, um einige der Einstellungen herauszuziehen. Wenn ich versuche, mit lein in einen Uberjar zu kompilieren, bekomme ich eine Rückverfolgung mit der Aufschrift "No so var: lb/settings".

Was fehlt mir? Gibt es eine eher idiomatische Möglichkeit, mit solchen App-weiten Einstellungen umzugehen? Ist es sicher, "def" innerhalb von -main zu verwenden, wie ich es bin, oder sollte ich ein Atom oder einen Verweis verwenden, um diesen Thread sicher zu machen?

Danke!

(ns com.domain.main 
    (:use com.domain.some-other-namespace.core) 
    (:gen-class)) 

(def settings {}) 

(defn -main [& args] 
    (with-command-line-args... ;set devel? based on args 
    (if (true? devel?) 
    (def settings (conj settings {:mongodb {:host "127.0.0.1"} 
         :memcached {:host "127.0.0.1"}})) 
    (def settings (conj settings {:mongodb {:host "PRODUCTION_IP"} 
         :memcached {:host "PRODUCTION_IP"}}))) 


;file2.clj 
(ns com.domain.some-other-namespace.core 
    (:require [main :as lb] 
    ...) 

;configure MongoDB 
(congo/mongo! 
    :db "dbname" :host (:host (mongodb lb/settings)))) 
... 

Antwort

0

Ein paar Dinge zu überprüfen:

typischerweise clojure Namensräumen haben mindestens eine. in ihnen project.main Ich denke, Leiningen kann davon abhängen.

Überprüfen Sie den Klassenordner, um sicherzustellen, dass die Hauptdatei- und andere Namespace-Klassendateien kompiliert werden.

+0

Alle Namespaces haben "." in ihnen. Ich verwende com.domain.module Formatierung für meine Namespaces. Ich habe es der Einfachheit halber weggelassen. Es hat gut funktioniert, bevor ich anfing, auf lb/settings zuzugreifen. – erikcw

4

Ok, ich habe das Problem gefunden. Es sieht so aus, als wäre es eine Zirkelreferenz. Ich war ":" com.domain.some-other-namespace.core aus com.domain.main. Da das "require" zuvor in com.domain.main (def settings {}) aufgerufen wurde, ist die Variable noch nicht vorhanden, wenn der andere Namespace kompiliert wird ...

Ich habe die Einstellungszuordnung in einen separaten Namespace verschoben (die Einstellungen natürlich geändert) und änderte es von einem Var zu einem Atom, nur um sicher zu sein. Scheint gut zu funktionieren!

Verwandte Themen