Синтаксис для эмуляции файлов свойств Java, который читается как Scheme, так и Clojure? - PullRequest
3 голосов
/ 21 января 2012

В качестве продолжения Используя Lisp или Scheme для конфигурирования Java-программ во время выполнения , я смотрю на наличие файла замены Java "замена", который может содержать код в дополнение к простым строкам Java.Файлы свойств Java выглядят следующим образом:

key1=value1
key2=value2
...

Ради забавы я играю со старым JScheme (из-за размера), но подумал о том, что было бы полезно иметь формат файла, совместимый с Clojure.,Это позволило бы использовать один и тот же синтаксис только для небольших «read my configuration» -использований, а также для более крупных систем, использующих Clojure.Идея заключается в том, что теперь значения можно оценивать вместо того, чтобы быть просто статическими строками.

Я не очень разбираюсь в Схеме или Clojure, но кажется, что vector доступен в обоих, но краткоСинтаксис cut отличается (#(...) по сравнению с [...]).

Существует ли синтаксис для представления структуры данных "свойства Java", которая является действительными программами Scheme и Clojure?Пожалуйста, покажите действительный код.


РЕДАКТИРОВАТЬ: После изучения предложения (props ...) и проработки некоторых навыков Lisp с помощью ELisp и JScheme я обнаружил, что

(list 
 "key1" "value1" 
 "key2" "value"
 )

можетбыть самым простым способом сделать это с синтаксисом не слишком далеко от файла свойств.

Ответы [ 3 ]

3 голосов
/ 23 января 2012

Самый простой и самый переносимый способ сделать это - использовать хорошее старомодное S-выражение списка.Используйте write (Схема) или pr (Clojure) для записи и read (оба Схема и Clojure )для чтения.(Нет необходимости использовать eval.)

Ваш пример будет выглядеть как S-выражение:

("key1" "value1"
 "key2" "value2")

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

(game
  (players (name "Alice"     score 5)
           (name "Bob"       score 10)
           (name "Catherine" score 20))
  (state 4321))
3 голосов
/ 21 января 2012

Если вы не хотите создавать макросы чтения схем для чтения литералов карты clojure (а clojure не поддерживает пользовательские макросы чтения), как насчет определения функции props:

(props 'key1 value1 'key2 value2 ...)

Теперь в ближайшем будущем определите реквизит как

(def props hash-map)

и аналогично схеме, вы можете просто оценить выражение props на любом языке.

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

0 голосов
/ 21 января 2012

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

Преимущества:

  • Это очень JSON-подобный, универсальный и гибкий формат
  • Вы можете просто прочитать его непосредственно через ридер Clojure (с read-string или подобным).Не нужно писать никаких синтаксических анализаторов!
  • Вы также можете включить код Clojure в структуру данных, которая может быть считана и скомпилирована читателем Clojure (хотя будьте осторожны с атаками внедрения кода, если вы делаете это!)
  • Вы получаете все преимущества, связанные с неизменяемой постоянной структурой данных

Синтаксис будет выглядеть примерно так:

{:key1 "Value1"
 :key2 "Value2"
 :function (fn [x] (* x x))}

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

 (:key2 property-map)
 => "Value2"
...