【问题标题】:Why can symbol in eval not be resolved?为什么无法解析eval中的符号?
【发布时间】:2015-03-09 14:07:00
【问题描述】:

为什么

((fn[x] (eval (symbol "x"))) 1)

炸毁Unable to resolve symbol: x in this context

我希望它的行为就像

((fn[x] x) 1)  

并评估为1

(如何)可以将前者修复为使用eval返回1吗?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    eval 不使用调用它的词法范围(由fnletloop 引入),它只看到通过当前命名空间映射的变量(绑定到变量@ 987654325@)。

    将词法绑定引入 eval 上下文将涉及手动将表单包装在 let 中,或者使用未记录的实现依赖主机互操作来查找并提供到 eval 上下文的词法绑定。

    手动包装 let 的示例(仅当 x 可以被 Clojure 阅读器读取时才有效):

    user=> (def x 0)
    #'user/x
    user=> (let [x 42] (eval 'x)) ; gets the global value of x, not local
    0
    user=> (let [x 42] (eval (list 'let ['x (list 'quote x)] 'x))) ; manually getting the local
    42
    

    【讨论】:

    • ... 因此,例如,(def x 3) ((fn[x] (eval (symbol "x"))) 1) 产生 3,而不是 1
    • 不知名的、无证的黑客攻击。我不太明白“手动包装”的意思。我可能遗漏了一些东西,但对我来说似乎真的没有办法从 eval 访问词法范围。
    • 我的意思是构造一个包含本地值的 let 块。 (eval (list 'let ['x x] 'x)
    • 编辑了答案,给出了一个更具体的例子来说明我的意思
    • 最后一个例子适用于42。试试(Object.)。 :)
    猜你喜欢
    • 1970-01-01
    • 2021-08-27
    • 2011-03-22
    • 2018-08-06
    • 2016-10-18
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 2018-11-11
    相关资源
    最近更新 更多