在 Racket 脚本中调用 `racket`
Invoke `racket` in a Racket script
一般问题:
我可以从 运行 Racket 脚本中调用当前的 racket
可执行文件吗?
基本上,如果 (find-executable-path "racket")
没有 return 我当前正在使用的 Racket 可执行文件的路径,我想替换 (system "racket ...")
。
上下文:
我真正想要的是尝试编译一些表达式并断言它们会引发编译错误。这是为了单元测试。
我认为您不需要在此处跳出可执行文件。试试这个:
#lang racket
(require syntax/modread)
;; define a namespace anchor to attach a namespace to:
(define-namespace-anchor anchor)
;; define a namespace for expansion:
(define target-namespace (namespace-anchor->namespace anchor))
(define program-to-compile
"#lang racket
(+ 3 4)")
;; go ahead and expand
(with-module-reading-parameterization
(λ()
(parameterize ([current-namespace target-namespace])
(expand
(read-syntax
"bogus-filename"
(open-input-string program-to-compile))))))
当我说 Racket 以一种有纪律的方式为 运行 程序提供编译器的能力时,我认为我是正确的。
如果您的目标只是编译一些球拍表达式,您可以使用任何一个 compile
or compile-syntax
来实现。示例文件为:
#lang racket
(require rackunit)
(define tests
(list #'(+ 1 "3")
#'(void void)
#'(string-append 4)))
(for/list ([t (in-list test)])
(check-exn exn:fail?
(lambda () (compile t))))
其中 exn:fail?
是您要查找的异常。
此外,如果您想要运行测试的一些通用语法上下文,您可以使用#`
#,
。所以你的代码最终会是这样的:
#lang racket
(require rackunit)
(define tests
(list #'(+ 1 "3")
#'(void void)
#'(string-append 4)))
(for/list ([t (in-list test)])
(check-exn exn:fail?
(lambda () (compile #`(module anonymous racket
#,t)))))
最后,如果您的代码存储在您的计算机上,您可以使用 John 的解决方案,同时使用 file->string
将文件转换为字符串。
对于小型测试,您还可以使用 syntax/macro-testing
库中的 convert-compile-time-error
。它将导致编译时错误的表达式转换为在计算时引发 运行 时错误的表达式。表达式使用它在模块中出现的环境,包括本地绑定;您不必 fiddle 命名空间和 eval
.
(check-exn #rx"bad syntax"
(lambda () (convert-compile-time-error (lambda))))
还有 convert-syntax-error
(在同一页上)。
一般问题:
我可以从 运行 Racket 脚本中调用当前的 racket
可执行文件吗?
基本上,如果 (find-executable-path "racket")
没有 return 我当前正在使用的 Racket 可执行文件的路径,我想替换 (system "racket ...")
。
上下文:
我真正想要的是尝试编译一些表达式并断言它们会引发编译错误。这是为了单元测试。
我认为您不需要在此处跳出可执行文件。试试这个:
#lang racket
(require syntax/modread)
;; define a namespace anchor to attach a namespace to:
(define-namespace-anchor anchor)
;; define a namespace for expansion:
(define target-namespace (namespace-anchor->namespace anchor))
(define program-to-compile
"#lang racket
(+ 3 4)")
;; go ahead and expand
(with-module-reading-parameterization
(λ()
(parameterize ([current-namespace target-namespace])
(expand
(read-syntax
"bogus-filename"
(open-input-string program-to-compile))))))
当我说 Racket 以一种有纪律的方式为 运行 程序提供编译器的能力时,我认为我是正确的。
如果您的目标只是编译一些球拍表达式,您可以使用任何一个 compile
or compile-syntax
来实现。示例文件为:
#lang racket
(require rackunit)
(define tests
(list #'(+ 1 "3")
#'(void void)
#'(string-append 4)))
(for/list ([t (in-list test)])
(check-exn exn:fail?
(lambda () (compile t))))
其中 exn:fail?
是您要查找的异常。
此外,如果您想要运行测试的一些通用语法上下文,您可以使用#`
#,
。所以你的代码最终会是这样的:
#lang racket
(require rackunit)
(define tests
(list #'(+ 1 "3")
#'(void void)
#'(string-append 4)))
(for/list ([t (in-list test)])
(check-exn exn:fail?
(lambda () (compile #`(module anonymous racket
#,t)))))
最后,如果您的代码存储在您的计算机上,您可以使用 John 的解决方案,同时使用 file->string
将文件转换为字符串。
对于小型测试,您还可以使用 syntax/macro-testing
库中的 convert-compile-time-error
。它将导致编译时错误的表达式转换为在计算时引发 运行 时错误的表达式。表达式使用它在模块中出现的环境,包括本地绑定;您不必 fiddle 命名空间和 eval
.
(check-exn #rx"bad syntax"
(lambda () (convert-compile-time-error (lambda))))
还有 convert-syntax-error
(在同一页上)。