Pregunta

Tengo un comportamiento extraño al verificar si se puede resolver un símbolo.

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

¿Alguien puede decirme de dónde podría venir esto? ¿Se pretende este comportamiento?

¿Fue útil?

Solución

(def ok "whatever") crea una variable nombrada ok en el momento de la compilación. El compilador escanea todo el formulario para compilarlo, descubre que definirá un var llamado ok, y lo crea para usted (sin vinculación), antes de que su forma se ejecute realmente. Cuando el def El formulario realmente se ejecuta, el valor de tiempo de ejecución de la expresión se asignará a la var user/ok. En su ejemplo, esto nunca sucede, porque el var ya ha sido creado y el if Branch va al otro lado.

Usando bound? Como sustituto, es una idea terrible, ya que prueba algo bastante diferente: si el VAR nombrado (que debe existir) tiene un enlace, ya sea permanente o local.

Otros consejos

Ya que solo lo uso dentro de una macro, ahora lo uso de la siguiente manera

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

Y ahora funciona ya que DEF está dentro del formulario citado y evaluado después de la resolución.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top