2016-06-14 1 views
1

나는이 같은 소스 파일에 정의 된 네임 스페이스에서 동적 VAR있어 :어떻게 Leiningen 사용자 repl에 var set! -able을 만드시겠습니까?

(ns mystuff.log ...) 

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

내가 set! REPL에서이 VAR 수 있도록하고 싶습니다, 같은 소스에서 그 코드 때문에 파일에서 볼 수 있습니다. 이 예에서 mystuff.log/log 매크로는 *logging*을보고 주어진 표현식을 인쇄할지 여부를 결정합니다. REPL에서는 (set! *logging* #{:whatever})으로 편리하고 세션 중에 여러 번 값을 변경합니다.

Leiningen의 REPL을 어떻게 허용 할 수 있습니까? 기본적으로 set!은 그러한 var에 IllegalStateException을 생성합니다. set!은 var의 루트 바인딩을 변경할 수 없기 때문입니다. var는 set!으로 변경할 수 있도록 스레드 로컬이어야합니다.

Leiningen이 REPL을 이와 같이 포장하여 var에 대한 스레드 로컬 바인딩을 만들도록 지시하는 방법이 있습니까? 그것은 가까운 무언가를 제공하는 것처럼 간단히 here 설명

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

:repl-options:init 옵션은, 보인다. 분명히 REPL은 :init을 호출하기 때문에 REPL에 입력 된 표현식에 대한 스레드 로컬 바인딩을 설정하기에는 너무 늦습니다.

답변

2

이 아닌 alter-var-root을 원할 수도 있습니다. 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과 같은 루트 바인딩을 수정하는 다른 양식과 동일한 규칙을 따릅니다.

+0

그렇다면,'user =>'프롬프트가 나타나기 전에 var가 thread-local 바인딩을 갖도록 Leiningen REPL을 어떻게 설정할 수 있습니까? 다시 말해, REPL은'바인딩 '안에 싸여있는 것처럼 실행되어야합니다. –

+0

한 발 뒤로 물러서서 무엇을하려고하는지 물어 봅시다. 'set! '은 루트 값을 변경하는 경우에 대한 대답이 극히 드물기 때문입니다. 대부분의 사람들은 이것을 필요로하지 않는 alter-var-root를 원하고 var에 값을 설정합니다. –

+0

난 그냥 사용자 정의 전역 변수의 값을 REPL에서 임의로 여러 번 변경할 수 있기를 원할 것입니다. (질문은 예를 보여줍니다 : 로그 집합으로 변경) –