2009-08-08 12 views
6

mam test mała jednostka makroPomoc w projektowaniu małą jednostka testowa Makro w Clojure

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

Jak poprawnie napisać komunikat o błędzie? Teraz daje

Clojure 1.0.0- 
1:1 user=> (is (+ 2 2) 4) 
user/yes 
1:2 user=> (is (+ 2 2) 5) 
Expected 5 In 4 But Evaluated to 4 

Chcę ocenić ekspresję i powiedzieć „tak, jeśli oceniano mecze wartości oczekiwanej inny druk błąd z unevaluated ekspresji zamiast wartości po«In».

Odpowiedz

11

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.

+0

Dzięki. Ale dlaczego stworzyłeś słowo kluczowe? Jaka byłaby różnica? – unj2

+1

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

+0

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

0

Masz problem z przekrojem, gdy masz wydruk makr "Is". Niech makro "Is" zwróci listę, która zawiera coś podobnego (: przekazać formalną odpowiedź-oczekiwaną-odpowiedź) lub (: nieudana odpowiedź-odpowiedź-oczekiwana-odpowiedź). Prawdopodobnie masz makro DefTest do agregowania swoich zapewnień. To jest miejsce, w którym powinieneś uzyskać odpowiedź.

Powiązane problemy