首页 文章

如何(重新)加载Racket(X)REPL中的文件?

提问于
浏览
8

假设我有一个类似的文件

#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 回答

  • 10

    由于以 #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使用模块的命名空间,因此您可以访问所有内容 . (并且您不需要 loadrequire 它 . )如果您更改了代码,也可以多次使用它来重新加载代码 . 但请注意,它存在一些问题,因此您可能需要安装nightly build才能使用它 .

    最后,您可能知道这一点,但与DrRacket合作将使事情变得更加容易 .

  • 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计划顶级水平是无望的”

相关问题