Организация Clojure Код

У меня есть программа, которая рисует фигуры на изображении. У меня есть отдельное пространство имен для каждой формы, и они находятся в отдельных файлах.


com/name/box.clj → имеет пространство имен com.name.box.
com/name/triangle.clj → имеет пространство имен com.name.triangle.

Все они имеют общую функцию с именем generate, которая рисует их на экране, поэтому, если я использую use, имена функций конфликтуют.

Теперь я загружаю их с помощью load-file. Есть ли лучший способ сделать это? Просматривая API Clojure, кажется, что есть несколько способов включения файлов. Какой вариант лучше для проекта с большим количеством файлов?

Ответ 1

Я тоже начал с помощью load-file. Согласно Clojure документации по libs,

Clojure определяет соглашения для именования и структурирования библиотек:
    * Имя библиотеки - это символ, который обычно содержит две или более части, разделенные периодами.
      * контейнер lib - это ресурс Java, чей путь относительного пути относитс к имени lib:
        o Путь - это строка
        o Периоды в имени lib заменяются слэшами в пути
        o Hyphens в имени lib заменяются символами подчеркивания в пути
        o Путь заканчивается на .clj
    *; lib начинается с формы" ns ", которая
      o создает пространство имен Clojure, которое разделяет его имя, и
      o объявляет свои зависимости от классов Java, Clojure основных средств и/или других библиотек

Документация Clojure также содержит следующий пример объявления пространства имен (который, я уверен, вы уже знаете, но я предоставляю его здесь для полноты):

(ns com.my-company.clojure.examples.my-utils
  (:import java.util.Date)
  (:use [clojure.contrib.def :only (defvar-)])
  (:require [clojure.contrib.shell-out :as shell]))

Итак, я бы хотел использовать libs для вашего проекта - это упростит все эти папки. Чтобы "включить" lib, вы будете использовать require, например:

(require 'clojure.contrib.def 'clojure.contrib.except 'clojure.contrib.sql)
(require '(clojure.contrib def except sql))

До тех пор, пока документация верна и ваш проект относителен к классу, все должно радостно загружаться. Надеюсь это ответит на твой вопрос.: D

Ответ 2

Наряду с использованием namespace libs, как уже было предложено, возможно, ваша общая функция "generate" является кандидатом на мультиметод? http://clojure.org/multimethods

Это поможет избежать столкновения имени функции и добавить общую абстракцию к вашим "фигурам", я думаю, это зависит от того, можно ли найти подходящую функцию отправки.