more doc updates for submodules
This commit is contained in:
parent
54a441c0e3
commit
a6a1b02de5
|
@ -52,8 +52,8 @@ racket
|
||||||
The relative reference @racket["cake.rkt"] in the import
|
The relative reference @racket["cake.rkt"] in the import
|
||||||
@racket[(require "cake.rkt")] works if the @filepath{cake.rkt} and
|
@racket[(require "cake.rkt")] works if the @filepath{cake.rkt} and
|
||||||
@filepath{random-cake.rkt} modules are in the same
|
@filepath{random-cake.rkt} modules are in the same
|
||||||
directory. (Unix-style relative paths are used for relative module
|
directory. Unix-style relative paths are used for relative module
|
||||||
references on all platforms, much like relative URLs in HTML pages.)
|
references on all platforms, much like relative URLs in HTML pages.
|
||||||
|
|
||||||
@; ----------------------------------------
|
@; ----------------------------------------
|
||||||
@section[#:tag "module-org"]{Organizing Modules}
|
@section[#:tag "module-org"]{Organizing Modules}
|
||||||
|
|
|
@ -207,3 +207,47 @@ and it should @italic{not} be used when a plain, portable
|
||||||
|
|
||||||
The automatic @filepath{.ss} and @filepath{.rkt} conversions apply as
|
The automatic @filepath{.ss} and @filepath{.rkt} conversions apply as
|
||||||
with other forms.}
|
with other forms.}
|
||||||
|
|
||||||
|
@; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@specsubform/subs[#:literals (submod)
|
||||||
|
(submod base element ...+)
|
||||||
|
([base module-path
|
||||||
|
"."]
|
||||||
|
[element id
|
||||||
|
".."])]{
|
||||||
|
|
||||||
|
Refers to a submodule of @racket[base]. The sequence of
|
||||||
|
@racket[element]s within @racket[submod] specify a path of submodule
|
||||||
|
names to reach the final submodule.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(module zoo racket
|
||||||
|
(module monkey-house racket
|
||||||
|
(provide monkey)
|
||||||
|
(define monkey "Curious George")))
|
||||||
|
(require (submod 'zoo monkey-house))
|
||||||
|
monkey
|
||||||
|
]
|
||||||
|
|
||||||
|
Using @racket["."] as @racket[base] within @racket[submod] stands for the
|
||||||
|
enclosing module. When a path of the form @racket[(#,(racket quote)
|
||||||
|
id)] refers to a submodule, it is equivalent to @racket[(submod "."
|
||||||
|
id)].
|
||||||
|
|
||||||
|
Using @racket[".."] as an @racket[element] cancels one submodule step, effectively
|
||||||
|
referring to the enclosing module. For example, @racket[(submod "." "..")]
|
||||||
|
refers to the enclosing module of the submodule in which the path
|
||||||
|
appears.
|
||||||
|
|
||||||
|
@examples[
|
||||||
|
(module zoo racket
|
||||||
|
(module monkey-house racket
|
||||||
|
(provide monkey)
|
||||||
|
(define monkey "Curious George"))
|
||||||
|
(module crocodile-house racket
|
||||||
|
(require (submod "." ".." monkey-house))
|
||||||
|
(provide dinner)
|
||||||
|
(define dinner monkey)))
|
||||||
|
(require (submod 'zoo crocodile-house))
|
||||||
|
dinner
|
||||||
|
]}
|
||||||
|
|
|
@ -26,13 +26,15 @@ The longhand form of a module declaration, which works in a
|
||||||
where the @racket[_name-id] is a name for the module,
|
where the @racket[_name-id] is a name for the module,
|
||||||
@racket[_initial-module-path] is an initial import, and each
|
@racket[_initial-module-path] is an initial import, and each
|
||||||
@racket[_decl] is an import, export, definition, or expression. In
|
@racket[_decl] is an import, export, definition, or expression. In
|
||||||
the case of a file, @racket[_name-id] must match the name of the
|
the case of a file, @racket[_name-id] normally matches the name of the
|
||||||
containing file, minus its directory path or file extension.
|
containing file, minus its directory path or file extension, but
|
||||||
|
@racket[_name-id] is ignored when the module is @racket[require]d
|
||||||
|
through its file's path.
|
||||||
|
|
||||||
The @racket[_initial-module-path] is needed because even the
|
The @racket[_initial-module-path] is needed because even the
|
||||||
@racket[require] form must be imported for further use in the module
|
@racket[require] form must be imported for further use in the module
|
||||||
body. In other words, the @racket[_initial-module-path] import
|
body. In other words, the @racket[_initial-module-path] import
|
||||||
bootstraps the syntax available in the body. The most commonly used
|
bootstraps the syntax that is available in the body. The most commonly used
|
||||||
@racket[_initial-module-path] is @racketmodname[racket], which supplies most
|
@racket[_initial-module-path] is @racketmodname[racket], which supplies most
|
||||||
of the bindings described in this guide, including @racket[require],
|
of the bindings described in this guide, including @racket[require],
|
||||||
@racket[define], and @racket[provide]. Another commonly used
|
@racket[define], and @racket[provide]. Another commonly used
|
||||||
|
@ -120,6 +122,108 @@ Unless otherwise specified, a module that is documented as a
|
||||||
@racketmodname[racket]. The documented language name can be used
|
@racketmodname[racket]. The documented language name can be used
|
||||||
directly with @racket[module] or @racket[require], too.
|
directly with @racket[module] or @racket[require], too.
|
||||||
|
|
||||||
|
@; ----------------------------------------------------------------------
|
||||||
|
@section[#:tag "submodules"]{Submodules}
|
||||||
|
|
||||||
|
A @racket[module] form can be nested within a module, in which case
|
||||||
|
the nested @racket[module] form declares a
|
||||||
|
@deftech{submodule}. Submodules can be referenced directly by the
|
||||||
|
enclosing module using a quoted name. The following example prints
|
||||||
|
@racket["Tony"] by importing @racket[tiger] from the @racket[zoo]
|
||||||
|
submodule:
|
||||||
|
|
||||||
|
@racketmod[
|
||||||
|
#:file "park.rkt"
|
||||||
|
racket
|
||||||
|
|
||||||
|
(module zoo racket
|
||||||
|
(provide tiger)
|
||||||
|
(define tiger "Tony"))
|
||||||
|
|
||||||
|
(require 'zoo)
|
||||||
|
|
||||||
|
tiger
|
||||||
|
]
|
||||||
|
|
||||||
|
Running a module does not necessarily run its submodules. In the above
|
||||||
|
example, running @filepath{park.rkt} runs its submodule @racket[zoo]
|
||||||
|
only because the @filepath{park.rkt} module @racket[require]s the
|
||||||
|
@racket[zoo] submodule. Otherwise, a module and each of its submodules can be run
|
||||||
|
independently. Furthermore, if @filepath{park.rkt} is compiled to a
|
||||||
|
bytecode file (via @exec{raco make}), then the code for
|
||||||
|
@filepath{park.rkt} or the code for @racket[zoo] can be loaded independently.
|
||||||
|
|
||||||
|
A @racket[module*] form is similar to a nested @racket[module] form,
|
||||||
|
but @racket[module*] inverts the possibilities for reference between
|
||||||
|
the submodule and enclosing module:
|
||||||
|
|
||||||
|
@itemlist[
|
||||||
|
|
||||||
|
@item{A submodule declared with @racket[module] can be
|
||||||
|
@racket[require]d by its enclosing module, but the submodule
|
||||||
|
cannot @racket[require] the enclosing module or lexically
|
||||||
|
reference the enclosing module's bindings.}
|
||||||
|
|
||||||
|
@item{A submodule declared with @racket[module*] can @racket[require]
|
||||||
|
its enclosing module, but the enclosing module cannot
|
||||||
|
@racket[require] the submodule. In addition, a @racket[module*]
|
||||||
|
form can specify @racket[#f] as its
|
||||||
|
@racket[_initial-module-path], in which case the submodule sees
|
||||||
|
all of the enclosing module's bindings---including bindings
|
||||||
|
that are not exported via @racket[provide].}
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
As an example of @racket[module*], the following variant of
|
||||||
|
@filepath{cake.rkt} includes a @racket[main] submodule that calls
|
||||||
|
@racket[print-cake]:
|
||||||
|
|
||||||
|
@racketmod[
|
||||||
|
#:file "cake.rkt"
|
||||||
|
racket
|
||||||
|
|
||||||
|
(provide print-cake)
|
||||||
|
|
||||||
|
(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))
|
||||||
|
]
|
||||||
|
|
||||||
|
Running a module does not run its @racket[module*]-defined submodules,
|
||||||
|
since the enclosing module cannot directly reference
|
||||||
|
@racket[module*]-defined submodules. Nevertheless, running the above
|
||||||
|
module via @exec{racket} or DrRacket prints a cake with 10 candles,
|
||||||
|
because the @racket[main] submodule} is a special case.
|
||||||
|
|
||||||
|
When a module is provided as a program name to the @exec{racket}
|
||||||
|
executable or run directly within DrRacket, if the module has a
|
||||||
|
@as-index{@racket[main] submodule}, the @racket[main] submodule is run after its
|
||||||
|
enclosing module. Declaring a @racket[main] submodule is often a
|
||||||
|
useful describe tests or other extra actions to be performed when a
|
||||||
|
module is run directly instead of @racket[required] as a library
|
||||||
|
within a larger program.
|
||||||
|
|
||||||
|
A @racket[main] submodule does not have to be declared with
|
||||||
|
@racket[module*]. If the @racket[main] module does not need to use
|
||||||
|
bindings from its enclosing module, it can be declared with
|
||||||
|
@racket[module]. A @racket[main] submodule typically uses the
|
||||||
|
bindings of its enclosing module, however, so @racket[main] is usually
|
||||||
|
declared with @racket[module*].
|
||||||
|
|
||||||
|
Submodules can be nested within submodules, and a submodule can be
|
||||||
|
referenced directly by a module other than its enclosing module by
|
||||||
|
using a @racket[submod] path as described in the
|
||||||
|
@seclink["module-paths"]{next section}.
|
||||||
|
|
||||||
@; ----------------------------------------------------------------------
|
@; ----------------------------------------------------------------------
|
||||||
|
|
||||||
@close-eval[cake-eval]
|
@close-eval[cake-eval]
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
@defmodule[syntax/modcode]
|
@defmodule[syntax/modcode]
|
||||||
|
|
||||||
@defproc[(get-module-code [path path?]
|
@defproc[(get-module-code [path path?]
|
||||||
|
[#:submodule-path submodule-path (listof symbol?) '()]
|
||||||
[#:sub-path compiled-subdir0 (and/c path-string? relative-path?) "compiled"]
|
[#:sub-path compiled-subdir0 (and/c path-string? relative-path?) "compiled"]
|
||||||
[compiled-subdir (and/c path-string? relative-path?) compiled-subdir0]
|
[compiled-subdir (and/c path-string? relative-path?) compiled-subdir0]
|
||||||
[#:compile compile-proc0 (any/c . -> . any) compile]
|
[#:compile compile-proc0 (any/c . -> . any) compile]
|
||||||
|
@ -24,7 +25,9 @@
|
||||||
any]{
|
any]{
|
||||||
|
|
||||||
Returns a compiled expression for the declaration of the module
|
Returns a compiled expression for the declaration of the module
|
||||||
specified by @racket[path].
|
specified by @racket[path] and @racket[submodule-path], where
|
||||||
|
@racket[submodule-path] is empty for a root module or a list for a
|
||||||
|
submodule.
|
||||||
|
|
||||||
The @racket[compiled-subdir] argument defaults to @racket["compiled"];
|
The @racket[compiled-subdir] argument defaults to @racket["compiled"];
|
||||||
it specifies the sub-directory to search for a compiled version of the
|
it specifies the sub-directory to search for a compiled version of the
|
||||||
|
|
|
@ -334,7 +334,8 @@ reading of the module language.}
|
||||||
@defproc[(make-meta-reader [self-sym symbol?]
|
@defproc[(make-meta-reader [self-sym symbol?]
|
||||||
[path-desc-str string?]
|
[path-desc-str string?]
|
||||||
[#:read-spec read-spec (input-port? . -> . any/c) (lambda (in) ....)]
|
[#:read-spec read-spec (input-port? . -> . any/c) (lambda (in) ....)]
|
||||||
[module-path-parser (any/c . -> . (or/c module-path? #f))]
|
[module-path-parser (any/c . -> . (or/c module-path? #f
|
||||||
|
(vectorof module-path?)))]
|
||||||
[convert-read (procedure? . -> . procedure?)]
|
[convert-read (procedure? . -> . procedure?)]
|
||||||
[convert-read-syntax (procedure? . -> . procedure?)]
|
[convert-read-syntax (procedure? . -> . procedure?)]
|
||||||
[convert-get-info (procedure? . -> . procedure?)])
|
[convert-get-info (procedure? . -> . procedure?)])
|
||||||
|
@ -367,6 +368,8 @@ description of the expected language form in the error message.
|
||||||
|
|
||||||
The result of @racket[read-spec] is converted to a module path using
|
The result of @racket[read-spec] is converted to a module path using
|
||||||
@racket[module-path-parser]. If @racket[module-path-parser] produces
|
@racket[module-path-parser]. If @racket[module-path-parser] produces
|
||||||
|
a vector of module paths, they are tried in order using
|
||||||
|
@racket[module-declared?]. If @racket[module-path-parser] produces
|
||||||
@racket[#f], a reader exception is raised in the same way as when
|
@racket[#f], a reader exception is raised in the same way as when
|
||||||
@racket[read-spec] produces a @racket[#f]. The @racketmodname[planet]
|
@racket[read-spec] produces a @racket[#f]. The @racketmodname[planet]
|
||||||
languages supply a @racket[module-path-parser] that converts a byte
|
languages supply a @racket[module-path-parser] that converts a byte
|
||||||
|
|
Loading…
Reference in New Issue
Block a user