在工作中我在尝试使用Scheme实现配置脚本时遇到了一个基本问题。为了避免发明一种人为的和受限制的语言,脚本应该包含实际的代码。稍后将对此代码进行评估。要使配置按需工作,必须能够访问某些变量。这些变量仅在评估的上下文中已知。因此,必须在当前环境中评估配置脚本。这是我所说的原始例子:
(let ((a #t))
(wr "a is ..."
(eval '(if a "true" "false"))))
运行此代码时,我总会收到一条错误消息,告诉我变量'a'未知。所以问题是:你知道如何评估当前环境中的冻结代码吗?
P.S。:我使用bigloo编译器。
///////////////////////////////////////////// 编辑://////////////////////////////////////////////// //////
当使用Chris建议的方法时,我遇到了另一个有趣的问题,即case关键字的用法。以下两个示例都使用相同的case结构,它应该触发输出“yes!”。线。不幸的是,他们的行为方式不同。
常用 - >输出是“是的!”正如所料:
(define testit "test")
(case testit
(("test")
(begin (newline) (write "yes!") (newline)))
(else
(begin (newline) (write "no!") (newline)))))
使用eval - >输出令人惊讶地“不”:
(define env (null-environment 5))
(eval '(define testit "test") env)
(eval '(case testit
(("test")
(begin (newline) (write "yes!") (newline)))
(else
(begin (newline) (write "no!") (newline)))))
这有意义吗?
答案 0 :(得分:5)
eval
无法访问词法变量,例如使用let
定义的变量。
相反,您必须创建一个环境,并使用您想要提供的变量填充它。例如:
(define env (null-environment 5))
(eval '(define a #t) env)
(wr "a is ..."
(eval '(if a "true" "false") env))
答案 1 :(得分:2)
要回答您的编辑,您不会将env作为参数传递给最后一个eval。如果没有给出参数,则eval创建的环境中不存在testit。
这可能是一个错字,但如果没有,那就是你的问题。