【问题标题】:How do you make a var set!-able in the Leiningen user repl?您如何在 Leiningen 用户 repl 中设置 var set!-able?
【发布时间】:2016-10-15 19:20:34
【问题描述】:

我在源文件中定义的命名空间中有一个动态变量,如下所示:

(ns mystuff.log ...)

(def ^:dynamic *logging* #{})

我希望能够set! REPL 中的这个 var,以便同一个源文件中的代码可以查看它。在此示例中,mystuff.log/log 宏查看 *logging* 以决定是否打印给定的表达式。在 REPL 中,(set! *logging* #{:whatever}) 会很方便,在会话期间多次更改其值。

我怎样才能让 Leiningen 的 REPL 允许这样做?默认情况下,set!ing 这样的 var 会产生 IllegalStateException,因为 set! 无法更改 var 的根绑定。 var 必须是线程本地的,才能被set! 更改。

有没有办法告诉 Leiningen 像这样包装它的 REPL,为 var 创建一个线程本地绑定?

(binding [mystuff.log/*logging* mystuff.log/*logging*]
  (the-leiningen-repl ...))

:repl-options:init 选项,简要解释了here,似乎提供了一些接近的东西。但显然,REPL 调用了:init,这使得为输入到 REPL 中的表达式建立线程本地绑定为时已晚。

【问题讨论】:

    标签: clojure leiningen read-eval-print-loop thread-local


    【解决方案1】:

    您可能想要alter-var-root,而不是set!。无需对 REPL 进行特殊设置或修改,您可以执行以下操作:

    user> (def logging #{})
    #'user/logging
    
    user> (alter-var-root #'logging conj :my-new-logger)
    #{:my-new-logger}
    
    user> (alter-var-root #'logging conj :another-new-logger)
    #{:my-new-logger :another-new-logger}
    
    user> logging
    #{:my-new-logger :another-new-logger}
    
    
    #{:my-new-logger :another-new-logger}
    

    set! 仅修改 var 的当前线程绑定。 alter-var-root 修改了 var 的根绑定:所有线程共享的值,它不会被每线程绑定覆盖。*


    *顺便说一句,这就是alter-var-root 没有感叹号的原因。它遵循与修改根绑定的其他形式相同的约定,例如def

    【讨论】:

    • 那么,如何设置 Leiningen REPL 以便 var 在出现 user=> 提示之前获得线程本地绑定?换句话说,REPL 应该像包裹在 binding 中一样运行。
    • 让我们退后一步,问问你想做什么。 set! 很少是更改根值的答案。大多数人想要不需要任何这些的alter-var-root,只需在var中设置值。
    • 我只是希望能够从 REPL 随意更改自定义全局变量的值,可能多次。 (问题举了一个例子:改变一组东西来记录。)
    • 啊,听起来alter-var-root 可能确实是我需要的。不是我所期望的!但实际上我不喜欢set! 的一点是它不能确保值绑定到一个集合(实际上我有一个小函数将隐含项合并到日志变量集合中),所以alter-var-root 似乎更可取。
    • alter-var-root 缺少 !出于同样的原因,def 不是def!,这基本上是约定和语言设计。 var 不像其他受控突变类型,并且根绑定不能保证在所有上下文中都是线程安全的,就像其他受控突变类型(确实使用!)注意:设置!不适用于 vars 它适用于由 vars 制成的线程局部变量。
    猜你喜欢
    • 2020-03-26
    • 2013-09-04
    • 2015-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-21
    • 2022-01-14
    • 1970-01-01
    相关资源
    最近更新 更多