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

Чтобы создать угловой радиус текстового поля ниже, ответ правильный:

swift 3

YourTextfieldName.layer.cornerRadius = YourTextfieldName.frame.size.height/2
YourTextfieldName.clipsToBounds = true
19
задан Tim Gilbert 12 June 2009 в 22:43
поделиться

1 ответ

Обновлено:

Предыдущая версия моего ответа был не очень прочным. Кажется, что это более простой и правильный способ сделать это, украденный из clojure.contrib.def :

(defmacro defn-plus [name & syms]
  `(defn ~(vary-meta name assoc :some-key :some-value) ~@syms))

user> (defn-plus ^Integer f "Docstring goes here" [x] (inc x))
#'user/f
user> (meta #'f)
{:ns #<Namespace user>, :name f, :file "NO_SOURCE_PATH", :line 1, :arglists ([x]), :doc "Docstring goes here", :some-key :some-value, :tag java.lang.Integer}

# ^ {} и with-meta не являются то же самое. Для объяснения разницы между ними см. Обсуждение Ричем в списке рассылки Clojure . Это все немного сбивает с толку и много раз встречается в списке рассылки; см. также здесь, например, .

Обратите внимание, что def - это особая форма, и она обрабатывает метаданные немного странно по сравнению с некоторыми другими частями языка. Он устанавливает метаданные var you ' re def fing к метаданным символа, который называет переменную; Думаю, это единственная причина, по которой все вышесказанное работает. См. Класс DefExpr в Compiler.java в исходном коде Clojure, если вы хотите увидеть всю глубину всего этого.

Наконец, страница 216 из Программирование Clojure ] говорит:

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

18
ответ дан 30 November 2019 в 04:59
поделиться