<p dir="ltr">I do not suggest rebinding the whole body like that; it could be seriously problematic if the user refers to something not viable to the macro definition. What you need to rebind is the name "rackunit" itself passed to require so that it has the context of the macro application. That way the names bound by the require will be visible to the macro user.</p>
<div class="gmail_quote">On Jan 8, 2014 5:29 PM, "Stephen Chang" <<a href="mailto:stchang@ccs.neu.edu">stchang@ccs.neu.edu</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
The problem is that check-true (and check-false) are not in scope (as<br>
you discovered) during expansion. Here is one way to fix your problem<br>
by recapturing the test expressions to have the proper context. You<br>
can also use syntax-local-introduce instead of the lambda (someone<br>
correct me if this is not proper usage).<br>
<br>
#lang racket<br>
(require (for-syntax syntax/parse))<br>
<br>
(define-syntax (define/test stx)<br>
(syntax-parse stx<br>
[(_ (id arg ...) body ... #:test test-body ...)<br>
(with-syntax ([id-str (symbol->string (syntax->datum #'id))]<br>
[(new-test-body ...)<br>
(map<br>
(λ (s) (datum->syntax #'here (syntax->datum s)))<br>
(syntax->list #'(test-body ...)))])<br>
#'(begin<br>
(define (id arg ...) body ...)<br>
(print id-str)<br>
(module+ test<br>
(require rackunit)<br>
(test-case id-str<br>
new-test-body ...))))]))<br>
<br>
(define/test (my-fn a b c)<br>
(print a)<br>
(print b)<br>
(print c)<br>
#:test<br>
(check-true #t)<br>
(check-false #t))<br>
<br>
On Wed, Jan 8, 2014 at 4:53 PM, Scott Klarenbach <<a href="mailto:scott@pointyhat.ca">scott@pointyhat.ca</a>> wrote:<br>
> I have the following macro:<br>
><br>
> (define-syntax (define/test stx)<br>
> (syntax-parse stx<br>
> [(_ (id arg ...) body ... #:test test-body ...)<br>
> (with-syntax ([id-str (symbol->string (syntax->datum #'id))])<br>
> #'(begin<br>
> (define (id arg ...) body ...)<br>
> (print id-str)<br>
> (module+ test<br>
> (require rackunit)<br>
> (test-case id-str<br>
> test-body ...))))]))<br>
><br>
> Which handles some testing boilerplate and allows me to use it like so:<br>
><br>
> (define/test (my-fn a b c)<br>
> (print a)<br>
> (print b)<br>
> (print c)<br>
> #:test<br>
> (check-true #t)<br>
> (check-false #t))<br>
><br>
> The problem is that the (require rackunit) expression inside of (module+<br>
> test) is not being picked up after macro expansion. Running either the code<br>
> or the tests (via raco test) results in: unbound identifier check-true.<br>
><br>
> Adding (module+ (require rackunit)) to the top of the file solves the<br>
> problem and both the file and tests run as expected.<br>
><br>
> What am I missing?<br>
><br>
> Thanks.<br>
> --<br>
> Talk to you soon,<br>
><br>
> Scott Klarenbach<br>
><br>
> PointyHat Software Corp.<br>
> <a href="http://www.pointyhat.ca" target="_blank">www.pointyhat.ca</a><br>
> p <a href="tel:604-568-4280" value="+16045684280">604-568-4280</a><br>
> e <a href="mailto:scott@pointyhat.ca">scott@pointyhat.ca</a><br>
> 200-1575 W. Georgia<br>
> Vancouver, BC V6G2V3<br>
><br>
> _______________________________________<br>
> To iterate is human; to recur, divine<br>
><br>
> ____________________<br>
> Racket Users list:<br>
> <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
><br>
<br>
____________________<br>
Racket Users list:<br>
<a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</blockquote></div>