一般的な質問:
racket
実行中の Racket スクリプト内から現在の実行可能ファイルを呼び出すことはできますか?
基本的に、現在使用している Racket 実行可能ファイルへのパスが返されない(system "racket ...")
場合の代替が欲しいです。(find-executable-path "racket")
環境:
私が本当に望んでいるのは、いくつかの式をコンパイルしてみて、コンパイル エラーが発生することをアサートすることです。これは単体テスト用です。
一般的な質問:
racket
実行中の Racket スクリプト内から現在の実行可能ファイルを呼び出すことはできますか?
基本的に、現在使用している Racket 実行可能ファイルへのパスが返されない(system "racket ...")
場合の代替が欲しいです。(find-executable-path "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
。ファイルの例は次のとおりです。
#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)))))
最後に、コードがコンピューターに保存されている場合は、ジョンのソリューションを使用file->string
しながら、ファイルを文字列に変換できます。
小さなテストの場合は、ライブラリconvert-compile-time-error
から使用することもできます。syntax/macro-testing
コンパイル時エラーの原因となる式を、評価時に実行時エラーを発生させる式に変換します。式は、ローカル バインディングを含め、モジュール内で発生する環境を使用します。名前空間と をいじる必要はありませんeval
。
(check-exn #rx"bad syntax"
(lambda () (convert-compile-time-error (lambda))))
もありますconvert-syntax-error
(同じページにあります)。