Background
- For more detail on modules refer to Chapter 6 Racket Guide.
What to do
- Corequisites
- tests
In quick we covered
the
Quick tutorial section on modules
We've also been using modules as part of
unit testing. In this section of the lab we we will further explore
modules, submodules, require
and provide
.
- create
hello.rkt
with the following content
#lang racket
(define (hello) (displayln "Hello world!"))
- You can test your new module by running
(hello)
- Following the racket guide,
replace
#lang racket
with a(module …)
form - add a test
(check-equal? (with-output-to-string hello) "Hello world!\n")
check-equal?
is defined in the modulerackunit
, so to get the above to compile we need to(require rackunit)
. Experiment a bit. Does it matter where you put(require rackunit)
?For now just add this to the module body, don't create a test submodule. Temporarily replace
displayln
withdisplay
to see a familiar bug caught by our test.Make a second file in the same directory, call it
application.rkt
.in
application.rkt
, require your module "hello.rkt", and call '(hello)'This fails, because we didn't export any bindings from "hello.rkt". Add
(provide hello)
. Again, observe that it doesn't matter too much where you put it: order of definition is less important in Racket than in some languages. By convention, bothrequire
andprovide
should be at the top of the module (or submodule).Often unit tests can take a noticable amount of time, or require things like network access not necessarily available to an application. To simulate a long running test, use begin and
sleep
(check-equal? (with-output-to-string hello) (begin (sleep 3) "Hello world!\n"))
Notice now that running "application.rkt" takes a long time. Fix this using the
(module+ test …)
form we already used (leave the test body as is).compare running "application.rkt" and "hello.rkt" from the command line with "racket filename" and "raco test filename".
We can see that just running "racket hello.rkt" doesn't seem to do much; it can be useful to have a module that acts a library (i.e. is
required
ed) and also as a program. Add a main submodule so that "racket hello.rkt" also invokes(hello)