如何通过命令行将文件加载到Racket中?

28

我一直在尝试通过命令行(通过'racket')启动 racket 程序,但一直没有成功。根据文档(这里),通过传递 -f,然后是一个文件名,应该能够评估该文件。然而,我似乎无法使其工作。作为一个测试,我创建了以下文件:

;test.rkt
#lang racket
(define a 1)

然后,在 racket 中运行它(假设已加载文件),并尝试调用变量 a 的值:

racket -f test.rkt -i
Welcome to Racket v5.1.1.
> a
reference to undefined identifier: a

我的最终目标是使用--main选项从一个shell脚本启动不同的程序,并结合使用-f来加载定义以启动执行。但我现在有些困惑,因为我似乎无法让这个微不足道的部分工作。

2个回答

33

移除 #lang 行是可行的,但这意味着你的代码不再是一个模块,这是一个相当糟糕的想法。要在给定的模块文件上启动 racket,只需要在文件上运行 racket,不需要其他任何东西。例如,将以下内容放入 test.rkt 文件中:

#lang racket/base
(printf "Hi\n")

只需使用racket test.rkt即可运行。如果您想要使用命令行标志,可以使用(current-command-line-arguments)获取额外命令行参数的向量,但也有racket/cmdline库,它可以更轻松地进行标准类型的标志处理。以下是一个示例:

#lang racket/base

(require racket/cmdline)

(define excitedness "")
(define mode "Hi")
(command-line
  #:multi
  [("-e" "--excited") "add excitedness levels"
   (set! excitedness (string-append excitedness "!"))]
  #:once-each
  [("-b" "--bye") "turn on \"bye\" mode"
   (set! mode "Bye")])

(printf "~a~a\n" mode excitedness)

现在你可以使用racket test.rkt <flags>来运行它。此外,还可以参考Racket Guide中的section on scripts,使你的test.rkt更容易运行。

最后,还有一个--main方法,你可能已经见过了--要使用它,你的模块需要提供一个main函数,该函数接收所有命令行标志作为参数。例如:

#lang racket/base
(require racket/string)
(provide main)
(define (main . xs)
  (printf "You gave me ~s flags: ~a\n"
          (length xs) (string-join xs ", ")))

并运行它:

racket -t /tmp/y -m -- foo bar baz

标志位的解释如下:-t 引入你的模块,-m 使 racket 运行你的 main 函数,-- 表示接下来的标志位都会传递给你的程序。你可以将这些标志组合在一起使用:

racket -tm- /tmp/y foo bar baz

这通常是放在脚本跳板中的内容,就像指南部分所描述的那样。

当然,所有这些都在参考手册中详细描述。


嗨,我有点困惑,当我执行 racket file.rkt 时,它会被评估,但是我想要 REPL,所以我执行 racket file.rkt -i,但没有出现 REPL?! - Vladimir Keleshev
7
如果您想在模块内使用 REPL,请像平常一样启动 Racket,然后使用 enter! 命令。或者,使用带有新的 xrepl 功能的夜间构建版本,它提供了更方便的 ,enter 命令。 - Eli Barzilay
现在我使用 enter!,但我想在 Vim 中制作一个快捷方式来评估和运行 REPL。有什么想法吗? - Vladimir Keleshev
我对vim并不是很了解--但这个想法不是和vi类似吗,你启动编辑器,写一些代码,然后退出,并在shell中运行一些东西吗?对于这种工作模式,我提到的新[XREPL](http://pre.racket-lang.org/docs/html/xrepl/)非常有用--你可以得到一个`,e`命令,它简单地在给定的文件上运行您的`$EDITOR`,默认为您输入的模块。 - Eli Barzilay
是的,这对我来说很理想,我正在下载夜间构建版本(虽然在 racket-lang.org 上很难找到)。我想知道 XREPL 之前的常规工作流程是什么?在 vim 中,您可以执行 shell 命令(并与其交互)而无需退出编辑器。因此,您可以将其设置为类似于 DrRacket(好吧,现在有了 XREPL)。我猜以前应该有一些解决方法...或者每个人都满意于 DrRacket,不需要另一个编辑器。 - Vladimir Keleshev

4

从您的文件中删除 #lang racket 标头:

;test.rkt
(define a 1)

谢谢!我想这一定是一个简单的问题 - 我太习惯在drracket中工作了,从来没有想到它可能会引起问题。 - Michael McGuinness
我想指出,我不会删除我的回答,因为它只是 Eli 下面的 TL;DR 版本。但你应该真的注意他。 - yarian
在不修改文件的情况下,使用shell很容易完成这个操作:racket -i -f <(tail -n +2 test.rkt) - ankh-morpork

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接