方案:正确应用eval函数



在工作中,当我尝试用Scheme实现配置脚本时,我遇到了一个基本问题。为了避免需要发明一种人为的和受限制的语言,脚本应该包含实际的代码。稍后将对该代码进行评估。要使配置按预期工作,它必须能够访问某些变量。这些变量只在求值的上下文中是已知的。因此,必须在当前环境中评估配置脚本。下面是我正在谈论的一个简单的例子:

(let ((a #t))
  (wr "a is ..."
    (eval '(if a "true" "false"))))

当运行这段代码时,我总是得到一个错误消息,告诉我变量'a'是未知的。所以问题是:您知道如何在当前环境中评估冻结的代码吗?

注::我使用bigloo编译器。

/////////////////////////////////////////////编辑 ://////////////////////////////////////////////////////

在使用Chris建议的方法时,我遇到了另一个有趣的问题,即case关键字的使用。下面两个示例都使用了相同的case结构,这将触发输出"yes!"行。不幸的是,它们的行为不同。

Usual ->输出如预期为"yes!":

  (define testit "test")
  (case testit
    (("test")
     (begin (newline) (write "yes!") (newline)))
    (else
      (begin (newline) (write "no!") (newline)))))

与eval ->输出令人惊讶的是"no":

  (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))))) 

这有意义吗?

eval不能访问使用let定义的词汇变量。

相反,您必须创建一个环境,并用您想要的变量填充它。例如:

(define env (null-environment 5))
(eval '(define a #t) env)
(wr "a is ..."
    (eval '(if a "true" "false") env))

要回答您的编辑,您没有将env作为参数传递给最后一个eval。如果没有给出参数,则在eval创建的环境中不存在test。

可能是打错了,如果不是,那就是你的问题了

相关内容

  • 没有找到相关文章

最新更新