2011-03-15 21 views
8

Estoy tratando de tomar una cadena y convertirla en un nombre de variable. Pensé que (make-symbol) o (interno) haría esto, pero aparentemente no es lo que quiero, o lo estoy usando incorrectamente.Crear un nombre de variable a partir de una cadena en Lisp

Por ejemplo:

> (setf (intern (string "foo")) 5) 
> foo 
    5 

Aquí estaría tratando de crear una variable llamada 'foo' con un valor de 5. A excepción, el código anterior me da un error. ¿Cuál es el comando que estoy buscando?

Respuesta

10

Hay una serie de cosas a tener en cuenta aquí:

  1. SETF no evalúa su primer argumento. Espera un símbolo o un formulario que especifique una ubicación para actualizar. Use SET en su lugar.

  2. Dependiendo de la antigüedad y la configuración de su implementación de Common Lisp, los nombres de los símbolos pueden aparecer en mayúsculas por defecto. Por lo tanto, la segunda referencia a foo puede referirse a un símbolo cuyo nombre es "FOO". En este caso, necesitaría usar (intern "FOO").

  3. La llamada a STRING es inofensiva pero innecesaria si el valor ya es una cadena.

Poniendo todo junto, intente esto:

> (set (intern "FOO") 5) 
> foo 
    5 
+0

¡Oye, eso funcionó! Especie de. En realidad, no intento asignar valores usando (establecer) sino usando otra función llamada (add-dm) que no creé. Aparentemente, (add-dm) tiene la misma limitación que (setf), donde la primera expresión no se evalúa, así que tendré que encontrar otra forma. Pero eso arrojó algo de luz sobre las cosas, ¡así que gracias! (Además, me doy cuenta de que (cadena) es innecesario, aunque mi objetivo final es crear un símbolo a partir de cadenas concatenadas, así que lo guardé por si hiciera una diferencia). – Jeff

+2

@Jeff Si 'ADD-DM' es una macro, podría expandirse a una función exportada que se puede usar de la misma manera que' SET '. Intente inspeccionar el resultado de '(macroexpand-1 '(add-dm ...))' para ver si tiene suerte. – WReach

+2

SET no es necesario. –

5

Uso:

CL-USER 7 > (setf (SYMBOL-VALUE (INTERN "FOO")) 5) 
5 

CL-USER 8 > foo 
5 

Esto también funciona con una variable:

CL-USER 11 > (let ((sym-name "FOO")) 
       (setf (SYMBOL-VALUE (INTERN sym-name)) 3)) 
3 

CL-USER 12 > foo 
3 

Recuerde también que, por defecto los símbolos se crean internamente como mayúsculas. Si desea acceder a un símbolo a través de una cadena, debe usar una cadena en mayúscula.

Cuestiones relacionadas