Primero, soy muy nuevo en el ceceo, por lo que es posible que me esté perdiendo algo muy obvio. Dicho esto, tengo Practical Common Lisp abierto al lado mío y CL Hyper Spec abierto en la siguiente pestaña, y no he podido resolver este problema:Common Lisp: ¿Por qué se transfieren símbolos al paquete incorrecto cuando se lee desde un archivo?
Estoy tratando de leer un árbol de un archivo y asignar valores a ranuras en una clase utilizando este código:
(defun load-char (file)
(with-open-file (in file)
(with-standard-io-syntax
(let ((chr-in (read in))
(chr (make-instance 'pc)))
(mapcar #'(lambda (x) (setf (slot-value chr (car x)) (cdr x))) chr-in)
chr))))
Cuando originalmente hackeado esto juntos y corrió bajo el paquete todo cl-usuario funcionaba perfectamente - yo estaba muy orgulloso de mí mismo, en realidad. El problema comenzó cuando empaqué esto junto con mi definición de clase y algunas funciones auxiliares en un nuevo paquete. Cargué el paquete usando asdf, luego usé (in-package :package-name)
para cambiar el paquete activo de mi REPL.
Ahora cuando ejecuto (load-char "/path/to/file")
me sale un error que dice que COMMON-LISP-USER::ID
(ID es la primera ranura en mi clase de pc) no existe, así que escribí esto para ver lo que estaba obteniendo cuando leí el archivo en:
(defun load-char-test (file)
(with-open-file (in file)
(with-standard-io-syntax
(let ((chr-in (read in))
(chr (make-hash-table)))
(mapcar #'(lambda (x) (setf (gethash (car x) chr) (cdr x))) chr-in)
(maphash #'(lambda (k v) (format t "~a: ~a~%" k v)) chr)
chr))))
Luego, en el REPL hago (defparameter hsh (load-char-test "/path/to/file"))
y todo va sin errores, y mis devuelve la llamada de formato exactamente lo que espero (SLOT: VALOR). Pero cuando hago un (gethash 'id hsh)
, devuelve NIL NIL
. Pero, cuando lo hago (gethash 'common-lisp-user::id hsh)
, devuelve el valor esperado.
Por lo tanto, estoy leyendo todo muy bien, pero todo en mi lista está siendo internado en el paquete COMMON-LISP-USER en lugar del que yo definí, y no puedo entender por qué. La ayuda es muy apreciada.
P.S. Lo siento si esta publicación es innecesariamente larga, solo quería mostrar que había intentado resolver esto por mi cuenta.
¿Es esto lo que quieres decir? http://pastebin.com/e0xmUAmp. Todavía está internado bajo cl-usuario. – oobivat
@oobivat: ver mi respuesta. El LET debe estar dentro de la macro WITH-STANDARD-IO-SYNTAX. –
Solucionado aquí: http://pastebin.com/f0V06uzm. Gracias por las respuestas rápidas. – oobivat