如何在racket lang(命令行...)函数中动态构建#:usage-help字符串?

时间:2016-01-17 10:32:14

标签: racket

我正在尝试构建一个git风格的CLI应用程序,例如racket-app command command-params ...。这类似于使用thorsub-command功能可以执行的操作。

我有这段代码:

(define commands
  (hash
   "noop"   (list "Does nothing"
                  (lambda () (log-info "noop was called :)")))
   "render" (list "Prepares and renders the static HTML (hugo)"
                  render-proc)))

(define s1 (build-possible-commands-from-the-keys-of-commands))

(define command
  (command-line
   #:usage-help s1
   #:args (op) op))

(cond
 [(dict-has-key? commands command) ((second (dict-ref commands command)))]
 [else (log-error "Unknown command")])

它以command-line: #:usage-help clause contains non-string失败。

如果我将s1的引用替换为实际字符串(例如"aoeu"),那么它的工作正常。我想动态地构建该字符串(在此示例中为s1),但我无法弄清楚如何做到这一点。

2 个答案:

答案 0 :(得分:3)

command-line的语法说:

flag-clause = ...
              #:usage-help string ...

这意味着command-line之后不会接受一般表达式 #:usage-help

我想不出这个限制的理由。我也希望接受一个表达。

我建议在Racket邮件列表中询问 - 也许某人有解释 - 或者如果没有,可能有人会改变command-line的行为。

答案 1 :(得分:3)

我认为这里的问题是usage-help必须是文字字符串,而不是程序运行时计算的字符串,因为这个字符串应该可以从命令行获得,而不用运行程序。也就是说,raco help应该能够在不运行程序的情况下提供帮助字符串。

你可以解决这个问题;你需要在扩展时提供字符串。这是最直截了当的方式:

#lang racket

(define-syntax my-cmd
  (syntax-rules ()
    [(_ str) 
     (define command
       (command-line
        #:usage-help str
        #:args (op) op))]))

(my-cmd "aoeu")

在这个例子中,很清楚我已经分离了"命令"从文字字符串调用,但它可能对你没用。

所以,这里有一个问题:用例是什么?你是如何在字符串上抽象的呢?

修改

在阅读了您的用例之后,我完全看起来像是想要使用parse-command-line,就像Jon Zeppieri在球拍邮件列表中所建议的那样。这允许您指定在参数解析失败时要调用的过程,并且您可以发出任何您喜欢的字符串。