假设我有一个类似的文件
#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)
工作,但这似乎相当......不直观和初学者不友好 .
这确实是应该这样做的方式吗?我应该简单地阅读模块和命名空间以轻松浏览和试验我的代码,还是有一种更简单的方法可以忽略?
注:我找到了How do you load a file into racket via command line?,但这只解释了如何运行该文件 . 不是如何在REPL中加载它,因此您可以测试/调试某些特定的定义,然后编辑,重新加载等 .
2 回答
由于以
#lang
开头的文件是模块,因此如果它们是load
则不会执行任何操作 . (实际上它有所作为,但可能不会对你有所帮助 . )最好完全避免使用load
,只是假装它不在那里 .现在,使用
require
是正确的,但它的作用是实例化模块并让您访问它提供的名称 . 在你的情况下,你没有't provide anything which means that you can'吨使用你的hello
. 为此,您可以将(provide hello)
添加到该文件 . 但是,'s likely not what you want, since it seems that you want to debug code. (Ie, you won' t想要从你的模块中获取所有东西,只是为了处理事情 . )所以正确使用的是
enter!
,或者如果你're using xrepl, then there'是一个更方便的,en
命令 . 这将实例化模块并使repl使用模块的命名空间,因此您可以访问所有内容 . (并且您不需要load
或require
它 . )如果您更改了代码,也可以多次使用它来重新加载代码 . 但请注意,它存在一些问题,因此您可能需要安装nightly build才能使用它 .最后,您可能知道这一点,但与DrRacket合作将使事情变得更加容易 .
将
#lang racket/base
放在文件的顶部将文件标记为模块形式(这是#lang shorthand);因此,加载文件只是添加(file "/tmp/hello.rkt")
的模块定义,正如您在需要该路径时发现的那样 .如果您只想尝试一组定义并尝试以交互方式加载它们,则可以尝试从文件顶部删除
#lang racket/base
. 我在一对"Racket toplevel"(rktl)文件中说明了这一点:请注意,以上述方式在顶层工作时存在很多陷阱 . 为了感受我正在谈论的内容,尝试谷歌搜索“球拍顶级水平是绝望的”或“plt计划顶级水平是无望的”