17.3.6 Module-Handling Configuration

top
up

17.3.6Module-Handling ConfigurationπŸ”— i

Suppose that the file "death-list-5.rkt" contains

"death-list-5.rkt"

(list "O-Ren Ishii"
"Vernita Green"
"Budd"
"Elle Driver"
"Bill")

If you require "death-list-5.rkt" directly, then it prints the list in the usual Racket result format:

> (require "death-list-5.rkt")

'("O-Ren Ishii" "Vernita Green" "Budd" "Elle Driver" "Bill")

However, if "death-list-5.rkt" is required by a "kiddo.rkt" that is implemented with scheme instead of racket:

"kiddo.rkt"

(require "death-list-5.rkt")

then, if you run "kiddo.rkt" file in DrRacket or if you run it directly with racket, "kiddo.rkt" causes "death-list-5.rkt" to print its list in traditional Scheme format, without the leading quote:

("O-Ren Ishii" "Vernita Green" "Budd" "Elle Driver" "Bill")

The "kiddo.rkt" example illustrates how the format for printing a result value can depend on the main module of a program instead of the language that is used to implement it.

More broadly, certain features of a language are only invoked when a module written in that language is run directly with racket (as opposed to being imported into another module). One example is result-printing style (as shown above). Another example is REPL behavior. These features are part of what’s called the run-time configuration of a language.

Unlike the syntax-coloring property of a language (as described in Source-Handling Configuration), the run-time configuration is a property of a module per se as opposed to a property of the source text representing the module. For that reason, the run-time configuration for a module needs to be available even if the module is compiled to bytecode form and the source is unavailable. Therefore, run-time configuration cannot be handled by the get-info function we’re exporting from the language’s parser module.

Instead, it will be handled by a new configure-runtime submodule that we’ll add inside the parsed module form. When a module is run directly with racket, racket looks for a configure-runtime submodule. If it exists, racket runs it. But if the module is imported into another module, the 'configure-runtime submodule is ignored. (And if the configure-runtime submodule doesn’t exist, racket just evaluates the module as usual.) That means that the configure-runtime submodule can be used for any special setup tasks that need to happen when the module is run directly.

Going back to the literal language (see Source-Handling Configuration), we can adjust the language so that directly running a literal module causes it to print out its string, while using a literal module in a larger program simply provides data without printing. To make this work, we will need an extra module. (For clarity here, we will implement this module as a separate file. But it could equally well be a submodule of an existing file.)

....(the main installation or the user’s space)
|-"literal"
|-"main.rkt"(with reader submodule)
|-"show.rkt"(new)
  • The "literal/show.rkt" module will provide a show function to be applied to the string content of a literal module, and also provide a show-enabled parameter that controls whether show actually prints the result.

  • The new configure-runtime submodule in "literal/main.rkt" will set the show-enabled parameter to #t. The net effect is that show will print the strings that it’s given, but only when a module using the literal language is run directly (because only then will the configure-runtime submodule be invoked).

These changes are implemented in the following revised "literal/main.rkt":

"literal/main.rkt"

(module readerracket
(require syntax/strip-context)
(provide (rename-out [literal-readread ]
[literal-read-syntaxread-syntax ])
get-info)
(define (literal-readin)
(literal-read-syntax#fin)))
(define (literal-read-syntaxsrcin)
(with-syntax ([str(port->stringin)])
#'(module anythingracket
(module configure-runtimeracket
(require literal/show)
(show-enabled#t))
(require literal/show)
(provide data)
(define data'str)
(showdata)))))
(define (get-infoinmodlinecolpos)
(lambda (keydefault)
(case key
[(color-lexer)
(dynamic-require 'syntax-color/default-lexer
'default-lexer)]
[else default]))))

Then the "literal/show.rkt" module must provide the show-enabled parameter and show function:

"literal/show.rkt"

(provide showshow-enabled)
(define show-enabled(make-parameter #f))
(define (showv)
(when (show-enabled)
(display v)))

With all of the pieces for literal in place, try running the following variant of "tuvalu.rkt" directly and through a require from another module:

"tuvalu.rkt"

#lang literal
Technology!
System!
Perfect!

When run directly, we’ll see the result printed like so, because our configure-runtime submodule will have set the show-enabled parameter to #t:

Technology!
System!
Perfect!

But when imported into another module, printing will be suppressed, because the configure-runtime submodule will not be invoked, and therefore the show-enabled parameter will remain at its default value of #f.

top
up

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /