Clojurescript развязал файл и пространство имен?

Я использую реагент для создания нескольких альтернативных корневых компонентов, только один из которых будет смонтирован на любой заданной странице; однозначно или/или. Они имеют определенную степень общности в своем составе, поэтому будет удобно переместить то, что является общим для них, в пространство имен common.

Было бы идеально, если бы в файле для каждого из этих компонентов у меня была возможность переключить пространство имен на common и добавить конкретное defs к компоненту, а затем переключиться обратно, таким образом избегая циклических зависимостей и не требуя какого-либо наследования.

Я вспомнил, что это возможно в Common Lisp, как это было замечательно, и это также кажется возможно в clojure.

Из документов Clojurescript: ns должна быть первой формой и может использоваться только один раз , а in-ns можно использовать только из реплики.

Мне интересно, есть ли способ добиться такого в clojurescript, который все еще ускользает от меня.

Если нет, мне, возможно, придется пересмотреть свои предположения относительно нескольких альтернативных корневых компонентов; идея множества сборок в рамках одной сборки, если это имеет смысл.

Обновление после некоторых дальнейших экспериментов и путаницы: другой вариант может состоять в том, чтобы разделить одно пространство имен на несколько файлов (это возможно?). Не знаю, в каком направлении здесь повернуть.

Тот факт, что в реагенте я использую атомы в глобальном пространстве имен, создает потребность в циклических зависимостях, если я использую отдельное пространство имен для общего. Следовательно, задумайтесь об одном глобальном пространстве имен, и в этом случае могут помочь несколько файлов. Или путь вперед один гигантский файл и одно пространство имен??

Обновление: я понял, что существует большое противоречие между глобальным сохранением всего состояния приложения (в моем текущем случае — нескольких атомов) и передачей состояния приложения. Мой шаблон в настоящее время является глобальным, не передавайте ничего из этого. Передача необходимого состояния в качестве параметров в fns в пространстве имен common решила бы здесь проблему (ага!), но тогда возникает вопрос, какие принципы здесь соблюдаются в отношении состояния приложения. Если бы я просто добавлял параметр всякий раз, когда он мне нужен, но начинал с идеи, что все глобально, в этом не было бы никакого реального принципа...


person mwal    schedule 19.09.2020    source источник


Ответы (1)


В ClojureScript все предварительно скомпилировано в один статический исполняемый файл JavaScript, поэтому нет ничего похожего на repl, к которому вы привыкли в Clojure. Действительно, в CLJS концепция Var на самом деле не связана с компилятором, это просто статические (постоянные) переменные, и их нельзя восстановить.

Сказав это, CLJS эмулирует поведение динамических переменных Clojure через форму binding, так что это может помочь вам достичь вашей цели. Как и в CLJ, он создает глобальную переменную (локальную для потока). Это вырожденный случай в CLJS, поскольку существует только один поток. Однако исходный код выглядит идентично случаю CLJ.

Другой способ добиться этого — просто использовать простую atom в качестве глобальной переменной, чтобы вам не приходилось передавать параметр.

Как всегда, использование глобальной переменной уменьшает количество параметров в деревьях вызовов функций, но создает невидимые зависимости между различными частями кода. Иногда это удобно, но обычно это плохой компромисс.

person Alan Thompson    schedule 21.09.2020