2016-06-20 12 views
1

Da jeder Clojure-Namespace einer Datei entspricht, ist es nicht möglich, dass eine öffentliche Funktion, ein Makro usw. niemals aus dieser Datei entfernt werden kann, ohne die Abwärtskompatibilität zu beeinträchtigen?Refactoring Clojure-Funktion außerhalb der Datei

Dies scheint ein überraschend starres System zu sein - im Wesentlichen kann das Refactoring von öffentlichem Code nur innerhalb einer einzigen Datei erfolgen.

Gibt es einen technischen Grund für diese Einschränkung? Vielleicht etwas mit Java Interop zu tun?

+3

Wie „eine Funktion/Methode aus einer Datei/Klasse zu bewegen, ohne zu brechen Abwärtskompatibilität“ in Java BTW – Davyzhu

+0

was gesagt @Davyzhu. Ich habe Schwierigkeiten zu sehen, wie das wichtig ist und wie es sich von anderen Programmiersprachen unterscheidet. –

Antwort

1

Sie können einen einzelnen Namespace in mehrere Dateien aufteilen (siehe Splitting a Clojure namespace over multiple files), aber dies ist sehr selten. Auch Sie können Vars mit https://github.com/ztellman/potemkin importieren, aber das wird auch in der Praxis selten gemacht. Clojure-Bibliotheken neigen dazu, relativ kleine öffentliche Schnittstellen zu haben, vielleicht weil sie normalerweise mit gemeinsamen Datenstrukturen arbeiten. Daher gibt es selten Dateien mit viel Code in ihnen.

Wenn Sie die Abwärtskompatibilität beibehalten möchten, können Sie def eine Variable in einen Namespace (oder sogar in einen Namespace mit einem anderen Namen) einfügen, um sicherzustellen, dass alle Anrufer weiterhin die richtige Funktion auflösen.

+0

Ich sehe, so ist es möglich, aber nicht üblich, einen einzelnen Namespace über mehrere Dateien zu teilen. Nun, das befreit zumindest die abstrakte Hierarchie des Codes drom vom physischen Medium der Dateien. –

1

Funktionen, die nicht als Teil der öffentlichen API betrachtet werden, können als privat gekennzeichnet werden, was die Möglichkeit für ein späteres Refactoring bietet, ohne den Funktionscode zu unterbrechen. Jegliche Änderungen an einer öffentlichen API werden natürlich die Abwärtskompatibilität gefährden und es wird einen Kompromiss zwischen dieser bahnbrechenden Änderung und der Einführung einer neuen API mit redundanter Funktionalität geben.

(ns foo) 

;; only visible in the foo ns 
(defn- a-private-fn [] ...) 

;; only visible in the foo ns 
(def ^:private a-private-var BAR 1)