Возможен ли «прозрачный» макролет?

Я хотел бы написать макрос Clojure с тестовыми тегами , который оборачивает кучу форм и добавляет некоторые метаданные к имени каждой сложной формы - в частности, добавить некоторые вещи в ключ : теги , чтобы я мог играть с помощью

Одна очевидная реализация для with-test- тэгов состоит в рекурсивном обходе всего тела, модифицируя каждую дефестированную форму, как я ее нахожу. Но я недавно прочитал Let Over Lambda , и он делает хороший пункт: вместо того, чтобы самостоятельно ходить по коду, просто оберните код в макролет и дайте компилятору пройтись по нему за вас. Что-то вроде:

(defmacro with-test-tags [tags & body]
  `(macrolet [(~'deftest [name# & more#]
                `(~'~'deftest ~(vary-meta name# update-in [:tags] (fnil into []) ~tags)
                   ~@more#))]
     (do ~@body)))

(with-test-tags [:a :b] 
  (deftest x (...do tests...)))

Это имеет очевидную проблему, однако, что ловкий макрос продолжает рекурсивно расширяться навсегда. Вместо этого я мог бы расширить его до clojure.test/deftest , избегая, таким образом, дальнейших рекурсивных расширений, но тогда я не могу с пользой вложить экземпляры с test- тэгов для маркировки подгрупп тестов.

На данный момент, особенно для такого простого, как ловкий , похоже, что сама ходьба по коду будет проще. Но интересно, знает ли кто-нибудь технику написания макроса, которая «слегка модифицирует» определенные подэкспрессии, не рекурсивно вечно.

Для любопытства: я рассмотрел некоторые другие подходы, такие как наличие binding -binding var, который я установил, как я иду вверх и вниз код, и использование этого var, когда я наконец вижу deftest , но так как каждый макрос возвращает только одно расширение, его привязки не будут на месте для следующего вызова макроэкспанда.

Отредактируйте

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

(defmacro with-test-tags [tags & body]
  (cons `do
        (postwalk (fn [form]
                    (if (and (seq? form)
                             (symbol? (first form))
                             (= "deftest" (name (first form))))
                      (seq (update-in (vec form) [1]
                                      vary-meta update-in [:tags] (fnil into []) tags))
                      form))
                  body)))

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

-121--813123- Джанго краткое описание для свойства кто-нибудь представляет, как добавить пользовательское имя к свойству в модели Джанго? Например, если я получил свойство: @ property def my_property (self): return u 'Возвращает некоторые вычисления', и я показываю это в...

Кто-нибудь знает, как добавить пользовательское имя к свойству в модели Django? Например, если у меня есть свойство

@property
def my_property(self):
     return u'Returns some calculations'

и я показываю его в admin в виде столбца:

class MyAdmin(admin.ModelAdmin):
    list_display=['my_property',]

Тогда я вижу столбец «My property» и то, что мне нужно, это столбец «Property X». Я пытался с my_property.short_description и my_property.verbose_name, ничего из этого не вышло.

21
задан alekwisnia 30 August 2011 в 09:14
поделиться