Original Odpowiedź
myślę, że to jest to, czego szukasz:
(defmacro is [expr value]
`(if (= ~expr ~value)
true
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
co (quote ~expr)
robi to przynieść S-wyrażenie reprezentowaną przez expr
do swojego „szablon”, ale uniemożliwia jej od oceny, a następnie zastosowanie str
do nienazwanego s-wyrażenia czyni go ciągiem do konkatenacji z innymi ciągami komunikatu o błędzie. Tak więc:
user=> (is (+ 2 2) 5)
Expected 5 In (+ 2 2) But Evaluated to 4
wywołuje pożądane zachowanie.
Zamiast używać 'yes
zgłosić sukces, można po prostu użyć true
w raporcie dla powodzenia testu, podając:
user=> (is (+ 2 2) 4)
true
i uniknięcie problemu 'yes
zwracane jako wykwalifikowany symbolem. Jeśli potrzebujesz symbol jakiegoś powodu, a następnie można dokonać kluczowe:
(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
Odpowiedź na pytanie zadane w komentarzach
Pytałeś w komentarzach:
Przepraszam, że powinienem być bardziej przejrzysty w moim pytaniu. Jaka byłaby różnica między symbolem a słowem kluczowym w tym przypadku?
rozważyć swoją pierwotną definicję (z korektą, aby błąd powrócić sposób chciał):
(defmacro is [expr value]
`(if (= ~expr ~value)
'yes
(println "Expected " ~value "In" (str (quote ~expr))
"But Evaluated to" ~expr)))
Wyobrażam sobie, że chcesz myślenie 'yes
że można użyć do przetestowania przed 'yes
w inny konteksty (często można zobaczyć te typy testów we wstępnych tekstach seplencyjnych). Ale 'yes
jest stosowany w definicji makra, zwraca się z wykwalifikowanym symbol, gdy test jest karnety:
user=> (is (+ 2 2) 4)
user/yes
Teraz, to nie jest to, czego chcesz.Wyobraź sobie, że powiedział:
user=> (= 'yes (is (+ 2 2) 4))
false
Aby uzyskać true
odpowiedź, trzeba by powiedzieć, że to (za pomocą cytatów składni):
user=> (= `yes (is (+ 2 2) 4))
true
Jeśli zdefiniowane makra, aby powrócić :yes
, wtedy uzyskać Rejestrowalne zwrotu bez konieczności składnia cytat z przedmiotu, którego używasz do zrobienia sprawdzanie:
user=> (= :yes (is (+ 2 2) 4))
true
Ale to wszystko jest zbędny, ponieważ jesteś naprawdę ja nterested tym, czy (+ 2 2)
zwrotów 4
, to znaczy, czy twierdzenie to true
lub false
zamiast czy 'yes
równa `` Tak or
„tak ; you can just have it return
true` i uniknąć tego kroku kontrolne (w realnym świecie).
W każdym przypadku, aby zrozumieć, jakie symbole są kwalifikowane, należy przeczytać docs on the clojure reader i this SO answer explaining the ins and outs of symbols in clojure.
Dzięki. Ale dlaczego stworzyłeś słowo kluczowe? Jaka byłaby różnica? – unj2
Problem z cytowanym symbolem polega na tym, że wychodzi on jak zakwalifikowany symbol, jak zauważyłeś. Zasugerowałem użycie "prawdziwego" jako najlepszego zamiennika, ale wyrzuciłem opcję użycia słowa kluczowego, jeśli z jakiegoś powodu potrzebowałeś czegoś "symbolika" z powodów, które musiałyby zrobić tak, jak napisałeś resztę programu. Myślę jednak, że "prawda" jest sposobem na streszczenie. – Pinochle
Przepraszam, że powinienem być bardziej przejrzysty w moim pytaniu. Jaka byłaby różnica między symbolem a słowem kluczowym w tym przypadku? – unj2