2012-01-14 4 views
7

Я получаю какое-то странное поведение при проверке, разрешен ли символ.Clojure: разрешение объявляет символ

user=> ok 
CompilerException java.lang.RuntimeException: Unable to resolve symbol: ok in this context, compiling:(NO_SOURCE_PATH:0) 
user=> (resolve 'ok) 
nil 
user=> (if (resolve 'ok) "bla" (def ok 'ok)) 
"bla" 
user=> ok 
#<Unbound Unbound: #'user/ok> 
user=> (def ok 'ok) 
#'user/ok 
user=> ok 
ok 

Может ли кто-нибудь сказать мне, откуда это может произойти? Предполагается ли это поведение?

+0

Какую версию Clojure вы используете? Я не вижу этого в 1.2.1 – spacemanaki

+1

@spacemanaki: Интересно, я просто воспроизвел это как в 1.2.1, так и в 1.3. Что-то странное, безусловно, происходит. –

+0

Моя ошибка, вторая ссылка на 'ok' привела к исключению вместо возврата объекта' # ', и я не обратил внимания. Для меня, на 1.2.1 '(разрешить 'ok)' внутри 'if', приводит к объявлению' ok'. – spacemanaki

ответ

4

(def ok "whatever") создает переменную с именем okво время компиляции. Компилятор просматривает всю форму для ее компиляции, обнаруживает, что вы будете определять переменную с именем ok и создает ее для вас (без привязки) до того, как ваша форма будет фактически выполнена. Когда форма def фактически выполняется, значение времени выполнения выражения будет присвоено переменной var user/ok. В вашем примере это никогда не происходит, потому что var уже создан, а ветка if идет в другую сторону.

Использование bound? в качестве замены - страшная идея, поскольку она проверяет что-то совсем другое: имеет ли названный var (который должен существовать) связывание, постоянное или поточно-локальное.

+0

звучит логично. Но тогда почему? (If (resolve 'x) x (def x' x)) 'yield' CompilerException java.lang.RuntimeException: Не удается разрешить символ: x в этом контексте, компилирование: (NO_SOURCE_PATH: 1) '? Или он пытается оценить x до того, как он создаст переменную? –

1

Так как я только использовать его внутри макроса я теперь использовать его следующим образ

(defmacro bla [x] 
    (if (resolve x) x `(def ~x '~x))) 

И теперь он работает с Защитой внутри цитируемой формы и оценивала после решимости.

 Смежные вопросы

  • Нет связанных вопросов^_^