Clojure: создание файлов, содержащих разрывы clojure с постоянными списками - PullRequest
0 голосов
/ 14 февраля 2012

Я задал связанный вопрос здесь: Clojure: Как превратить код clojure в строку, которая может быть оценена?В основном это работает, но списки переводятся в необработанные парены, что не получается

Ответ был великолепным, но я понял, что это не совсем то, что мне нужно.Я упростил пример для stackoverflow, но я не просто записываю данные, я пытаюсь выписать определения функций и другие вещи, которые содержат структуры, содержащие списки.Итак, вот простой пример (из последнего вопроса).

Я хочу создать файл, который содержит функцию:

(defn aaa []
  (fff :update {:bbb "bbb" :xxx [1 2 3] :yyy (3 5 7)}))

Все, что после: update является структуройУ меня есть доступ при записи файла, поэтому я вызываю str для него, и он появляется в этом состоянии.Это нормально, но список, когда я загружаю файл для этой сгенерированной функции, пытается вызвать 3 как функцию (так как это первый элемент в списке).

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

Ответы [ 3 ]

1 голос
/ 14 февраля 2012

Вам необходимо quote структуру до получения строкового представления:

(list 'quote foo)

где foo - это структура.

Три дополнительных замечания:

  1. обход кода для цитирования всех списков / секвенций вообще не будет выполняться, поскольку форма (defn ...) верхнего уровня также будет заключена в кавычки;

  2. списки - не единственный потенциально проблемный тип - это еще один символ (+ против #<core$_PLUS_ clojure.core$_PLUS_@451ef443>);

  3. вместо использования (str foo) (даже с foo уже в кавычках), вы, вероятно, захотите распечатать цитированный foo - или, скорее, весь кодовый блок с foo в кавычках внутри - используя pr / prn.

Последний пункт требует короткого обсуждения. pr явно обещает создать читаемое представление, если *print-readably* равно true, тогда как str создает такое представление только для составных структур данных Clojure «случайно» (реализации) и все еще только если *print-readably* is true:

(str ["asdf"])
; => "[\"asdf\"]"

(binding [*print-readably* false]
  (str ["asdf"]))
; => "[asdf]"

Вышеупомянутое поведение обусловлено clojure.lang.RT/printString (это то, что структуры данных Clojure в конечном итоге делегируют свои toString потребности) в использовании clojure.lang.RT/print, который, в свою очередь, выбирает формат вывода в зависимости от значения *print-readably* .

Даже если *print-readably* привязан к true, str может привести к выходу, не подходящему для потребления clojure.lang.Reader: например, (str "asdf") - это просто "asdf", а читаемое представление - "\"asdf\"". Используйте (with-out-str (pr foo)), чтобы получить строковый объект, содержащий представление foo, гарантированно читаемое, если *print-readably* равно true.

0 голосов
/ 14 февраля 2012

Попробуйте вместо этого ...

(defn aaa []
  (fff :update {:bbb "bbb" :xxx [1 2 3] :yyy (list 3 5 7)}))
0 голосов
/ 14 февраля 2012

Оберните это в вызов к quote, чтобы прочитать его, не оценив его.

...