[英]Invoke `racket` in a Racket script
一般問題:
我可以在正在運行的Racket腳本中調用當前的racket
可執行文件嗎?
基本上,在(find-executable-path "racket")
沒有返回我正在使用的Racket可執行(find-executable-path "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
compile-syntax
或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
。 它將一個表達式導致編譯時錯誤進入表達式,該表達式在計算時會引發運行時錯誤。 表達式使用模塊中出現的環境,包括本地綁定; 你不必操作命名空間和eval
。
(check-exn #rx"bad syntax"
(lambda () (convert-compile-time-error (lambda))))
還有convert-syntax-error
(在同一頁面上)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.