Справка в разработке маленького Макроса Модульного теста в Clojure

append добавляет, что элемент к списку, и extend связывает первый список с другим списком (или другой повторяемый, не обязательно список.)

>>> li = ['a', 'b', 'mpilgrim', 'z', 'example']
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']

>>> li.append("new")
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']

>>> li.append(["new", 2])
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]

>>> li.insert(2, "new")
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2]]

>>> li.extend(["two", "elements"])
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', ['new', 2], 'two', 'elements']

От Погружение в Python .

6
задан unj2 8 August 2009 в 14:24
поделиться

2 ответа

Исходный ответ

Я думаю, это то, что вы ищете:

(defmacro is [expr value]
    `(if (= ~expr ~value)
         true
         (println "Expected " ~value "In" (str (quote ~expr)) 
                  "But Evaluated to" ~expr)))

то, что делает (quote ~ expr) , это переносит s-выражение, представленное expr , в ваш "шаблон", но предотвращает его оценку, затем применение str к неоцененному s-выражению превращает его в строку для конкатенации с другими строками сообщения об ошибке. Итак,:

user=> (is (+ 2 2) 5)
Expected  5 In (+ 2 2) But Evaluated to 4

производит желаемое поведение.

Вместо того, чтобы использовать 'yes для сообщения об успехе, вы можете просто использовать true в качестве отчета об успешном выполнении теста, давая:

user=> (is (+ 2 2) 4)
true

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

(defmacro is [expr value]
    `(if (= ~expr ~value)
         :yes
         (println "Expected " ~value "In" (str (quote ~expr)) 
                  "But Evaluated to" ~expr)))


user=> (is (+ 2 2) 4)
:yes



Ответ на вопрос, заданный в комментариях

Вы спросили в комментариях:

Мне жаль, что я должен был быть более ясным в своем вопросе. В чем будет разница между символом и ключевым словом в этом случае?

Рассмотрим ваше исходное определение (с исправлением, чтобы ошибка возвращалась так, как вы хотели):

(defmacro is [expr value]
`(if (= ~expr ~value)
     'yes
     (println "Expected " ~value "In" (str (quote ~expr)) 
              "But Evaluated to" ~expr)))

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

user=> (is (+ 2 2) 4)
user/yes

Теперь это не то, что вам нужно. Представьте, что вы сказали это:

user=> (= 'yes (is (+ 2 2) 4))
false

Чтобы получить истинный ответ, вам нужно будет сказать следующее (используя синтаксическую цитату):

user=> (= `yes (is (+ 2 2) 4))
true

Если вы определили свой макрос для возврата : yes , то вы получите проверяемый возврат без необходимости цитировать синтаксис объект, который вы используете для проверки:

user=> (= :yes (is (+ 2 2) 4))
true

Но это все лишнее, потому что вас действительно интересует, возвращает ли (+ 2 2) 4 , т. Е. Является ли ваше утверждение истинным или ложным , а не тем, что 'да равно «да или ' да ; вы можете просто вернуть true` и избежать этого шага проверки (в реальном мире).

В любом случае, чтобы понять, что такое квалифицированные символы,

11
ответ дан 9 December 2019 в 22:38
поделиться

При печати макроса «Is» возникает проблема пересечения. Сделайте так, чтобы макрос 'Is' возвращал список, который содержит что-то вроде этого (: передать форму фактического ответа ожидаемый-ответ) или (: ошибка формы ожидаемого ответа фактического ответа). Вероятно, у вас есть макрос DefTest для агрегирования ваших утверждений. Здесь вы должны написать свой ответ.

0
ответ дан 9 December 2019 в 22:38
поделиться