假设我有一个像
这样的文件#lang racket/base
(define (hello) (print "Hello"))
... more definitions ...
我希望在文件中加载定义,以便在(X)REPL中以交互方式使用它们。我该怎么做?
如果我启动(X)REPL和(load "/tmp/hello.rkt")
,则我无法使用hello
函数:
-> (hello)
; hello: undefined;
如果我(require (file "/tmp/hello.rkt"))
,结果是一样的。现在我可以 (enter! (file "/tmp/hello.rkt"))
,然后(hello)
可以正常工作,但这似乎是......不直观且初学者不友好。
这确实是应该这样做的方式吗?我应该阅读模块和命名空间以轻松浏览和试验我的代码,还是有一种更简单的方法可以忽略?
N.B。我找到了How do you load a file into racket via command line?,但这只解释了如何运行文件。不是如何在REPL中加载它,所以你可以测试/调试一些特定的定义,然后编辑,重新加载等。
答案 0 :(得分:10)
由于以#lang
开头的文件是模块,因此如果您load
它们则不会执行任何操作。 (实际上它做了一些事情,但可能不会对你有所帮助。)最好避免完全使用load
,只是假装它不存在。
现在,使用require
是正确的,但它的作用是实例化模块并让您访问它提供的名称。在您的情况下,您没有提供任何意味着您无法使用hello
的内容。为此,您可以将(provide hello)
添加到文件中。但这可能不是你想要的,因为你似乎想调试代码。 (即,您不希望provide
来自您的模块的所有内容,只是为了处理事情。)
所以正确使用的是enter!
,或者如果你正在使用xrepl,那么有一个更方便的,en
命令。这将实例化模块并使repl使用模块的命名空间,因此您可以访问所有内容。 (并且您不需要load
或require
它。)如果您更改了代码,也可以多次使用它来重新加载代码。但请注意,它存在一些问题,因此您可能需要安装nightly build才能使用它。
最后,您可能知道这一点,但与DrRacket合作会让事情变得更容易。
答案 1 :(得分:3)
将#lang racket/base
放在文件的顶部将文件标记为模块形式(这是#lang shorthand);因此,加载文件只是添加(file "/tmp/hello.rkt")
的模块定义,正如您在需要该路径时所发现的那样。
如果您只想尝试一组定义并尝试以交互方式加载它们,则可以尝试从文件顶部删除 #lang racket/base
。我在这里用一对“Racket toplevel”(rktl)文件来说明这一点:
% cat hello-unhashed.rktl
(define (hello) (print "Hello") (newline))
% cat hello2-unhashed.rktl
(define (hello) (print "Hello2") (newline))
% racket
Welcome to Racket v5.3.2.
> (load "hello-unhashed.rktl")
> (hello)
"Hello"
> (load "hello2-unhashed.rktl")
> (hello)
"Hello2"
> (load "hello-unhashed.rktl")
> (hello)
"Hello"
> (exit)
%
请注意,以上述方式在顶层工作时存在很多陷阱。为了感受我正在谈论的内容,尝试谷歌搜索“球拍顶级水平是绝望的”或“plt计划顶级水平是无望的”