-
Notifications
You must be signed in to change notification settings - Fork 21
/
06.2.4 main和test子模块
86 lines (57 loc) · 3.09 KB
/
06.2.4 main和test子模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
6.2.4 main和test子模块
下面“cake.rkt”的变体包括一个main子模块,它调用print-cake:
"cake.rkt"
#lang racket
(define (print-cake n)
(show " ~a " n #\.)
(show " .-~a-. " n #\|)
(show " | ~a | " n #\space)
(show "---~a---" n #\-))
(define (show fmt n ch)
(printf fmt (make-string n ch))
(newline))
(module* main #f
(print-cake 10))
运行一个模块不会运行module*定义的子模块。尽管如此,还是可以通过racket或DrRacket运行上面的模块打印一个带10支蜡烛的蛋糕,因为main子模块是一个特殊情况。
当一个模块作为一个可执行程序的名称提供给racket在DrRacket中直接运行或执行在,如果模块有一个main子模块,main子模块会在其外围模块之后运行。当一个模块直接运行时,声明一个main子模块从而指定额外的行为去被执行,以代替require作为在一个较大程序里的一个库。
一个main子模块不必用module*声明。如果main模块不需要使用其外围模块的绑定,则可以用module声明它。更通常的是,main使用module+声明:
(module+ name-id
decl ...)
用module+申明的一个子模块就像一个由module*用#f代替initial-module-path申明的模块。此外,多个module+表可以指定相同的子模块名称,在这种情况下,module+表的主体被组合起来以创建一个单独的子模块。
module+的组合行为对定义一个test子模块是非常有用的,它可以方便地使用raco test运行,用同样的方式main也可以方便地使用racket运行。例如,下面的“physics.rkt”模块输出drop和to-energy函数,它定义了一个test模块支持单元测试:
"physics.rkt"
#lang racket
(module+ test
(require rackunit)
(define ε 1e-10))
(provide drop
to-energy)
(define (drop t)
(* 1/2 9.8 t t))
(module+ test
(check-= (drop 0) 0 ε)
(check-= (drop 10) 490 ε))
(define (to-energy m)
(* m (expt 299792458.0 2)))
(module+ test
(check-= (to-energy 0) 0 ε)
(check-= (to-energy 1) 9e+16 1e+15))
引入“physics.rkt”到一个更大的程序不会运行drop和to-energy测试——即使引发这个测试代码的加载,如果模块被编译——但在运行raco test physics.rkt的时候会同时运行这个测试。
上述“physics.rkt”模块相当于使用module*:
"physics.rkt"
#lang racket
(provide drop
to-energy)
(define (drop t)
(* 1/2 49/5 t t))
(define (to-energy m)
(* m (expt 299792458 2)))
(module* test #f
(require rackunit)
(define ε 1e-10)
(check-= (drop 0) 0 ε)
(check-= (drop 10) 490 ε)
(check-= (to-energy 0) 0 ε)
(check-= (to-energy 1) 9e+16 1e+15))
使用module+代替module*允许测试与函数定义交叉。
module+的组合行为有时对main模块也有帮助。即使组合是不需要的,(module+ main ....)仍是首选,因为它比(module* main #f ....)更具可读性。