1

どこかでいくつかのシンボルを定義したとします:

#lang racket
(define foo 123)
(define bar '("1" "2" "3"))

"foo = 123"またはのような文字列を生成する方法が必要"bar = '("1" "2" "3")"です。そのための関数を書きました:

(define (f2 sy)
  (format "~a = ~s" sy (eval sy)))

この関数は、インタプリタ ウィンドウでうまく機能します。

> (f2 'foo)
"foo = 123"
> (f2 'bar)
"bar = (\"1\" \"2\" \"3\")"

それは私にとって非常に満足です。ただし、コードで使用すると、

foo: unbound identifier;
 also, no #%top syntax transformer is bound in: foo

何か間違ったことをしているような気がします。私の問題を解決する正しい方法を教えてください。

PS:私は使用していますDrRacket, version 5.3.1

4

2 に答える 2

1

まず第一にeval、Racket の最後の手段としてのみ使用する必要があります。プログラムの効率が低下し、理解しにくくなります。これを行う正しい方法は、おそらく次のようなマクロを作成することです。

(define-syntax-rule (f2 sy)
  (format "~a = ~s" (quote sy) sy))

(define foo 2)
(f2 foo)

このマクロは、ルックアップする変数の名前を本文のフォーマット式に置き換えるだけです。はquote、変数名を出力可能なシンボルに変換します。このマクロはプロシージャとしては機能しません。名前を出力する前に参照して(f2 foo)しまうからです。fooquote


eval注: yourが期待どおりに機能しない理由evalは、スコープ内の内容を決定する名前空間に対して常に評価されるためです。モジュール内のデフォルトの名前空間には何も含まれていないため、他のものevalを見ることはできませfooん。名前空間の詳細については、ガイドを参照してください。

于 2013-03-10T15:57:53.097 に答える
1

Asumu Takikawa に触発された別の解決策は、ガイドに記載されているトリックを使用します。

(define-namespace-anchor a)
(define ns (namespace-anchor->namespace a))

(define (f2 sy)
  (format "~a = ~s" sy (eval sy ns)))

マクロを使用したソリューションとは対照的に、この機能はマッピングできます。

于 2013-03-10T20:20:01.180 に答える