Estoy trabajando en la optimización de mi configuración de emacs donde puedo crear dinámicamente funciones interactivas para todos los temas que tengo en una lista.
A continuación se muestra una versión simplificada de la construcción que estoy tratando de hacer funcionar.
;; List containing names of functions that I want to create
(setq my/defun-list '(zz-abc
zz-def
zz-ghi))
;; Elisp macro to create an interactive defun whose name
;; is passed as the macro argument
(defmacro my/create-defun (defun-name)
`(defun ,defun-name ()
(interactive)
(let ((fn-name (symbol-name ',defun-name)))
(message "Testing creation of function %s" fn-name))))
;; Loop to call the above macro for each element in the list
;; DOES *NOT* WORK
(dolist (name my/defun-list)
(my/create-defun name))
Pero si desenrollo el bucle manualmente, funciona:
;; WORKS
(my/create-defun zz-abc)
(my/create-defun zz-def)
(my/create-defun zz-ghi)
Pero a continuación no funciona donde paso los nombres de los símbolos (que probablemente sea lo que sucede cuando el bucle se desenrolla solo). Tenga en cuenta las comillas antes de los argumentos macro.
;; DOES *NOT* WORK
(my/create-defun 'zz-abc)
(my/create-defun 'zz-def)
(my/create-defun 'zz-ghi)
Actualizar
Gracias a la ayuda de @wvxvw , ¡ finalmente conseguí que esto funcionara !
Como @wvxvw sugiere, no generaré desfuns generadores de lotes para todos y cada uno de los casos de uso. Este fue un caso de uso especial donde para un tema llamado XYZ
, quiero generar un defun llamado load-theme/XYZ
que hace el trabajo de
- Deshabilitar todos los demás temas que puedan estar activos
- llamar
load-theme
paraXYZ
- Haciendo algunas cosas más personalizadas relacionadas con ese tema; Paso la configuración personalizada para cada tema a través de la
my/themes
lista.
fuente
defuns
dentro de aprogn
.progn
se permite que sea un formulario de nivel superior (en el sentido de que todo lo que se aplica a los formularios de nivel superior también se aplica al contenido deprogn
). Pero cuestionaría la lógica de crear funciones de esa manera: ¿por qué no tener, por ejemplo, una tabla has con lambdas como valores?cons
es pero planeo convertirlos en listas con propiedades personalizadas para cada tema.(my/create-defun name)
3 veces, por lo que deberías terminar definiendo una función llamadaname
3 veces.Respuestas:
Aquí hay un intento de explicación y alguna sugerencia.
Ahora, intentemos solucionar esto:
Ejemplo con lectura de nombres de funciones de una variable
El problema era de tipo conceptual: las macros son para generar código cuando el entorno quiere leerlo. Cuando ejecuta el código usted mismo (como usuario de su programa), esto ya es demasiado tarde para hacerlo (el entorno ya debería saber qué es el programa).
Una nota marginal: aconsejaría no agrupar varios
defuns
. La razón es que hace que la depuración sea mucho más complicada. La poca redundancia que tiene en las definiciones repetidas se paga muy bien durante la fase de mantenimiento (y el mantenimiento suele ser la fase más larga en la vida útil del programa).fuente
mapcar
descubra el uso con listas. Esto no parece funcionar con mi caso de uso real. Investigaré esto tan pronto como pueda.(mapcar (lambda (x) (message "argument: %s" x)) some-alist)
para ver cuál es el argumento que obtienes, y trabajar desde allí. Si esa es una lista asociativa, me imagino que la salida es algo asíargument: (foo . bar)
, entonces podría accederfoo
usandocar
ybar
usandocdr
funciones.nth
fn en lugar decar
ycadr
) pero elsequencep
check-inmapcar
erró. Estaba proporcionando una lista como entrada, pero todavía mapcar no creía que fuera una secuencia. Si lo hice(sequencep my-alist)
, eso no fue nulo. Así que estoy confundido ... todavía tengo que depurar eso.my-alist
fuenil
o olvidaste (o agregaste más) comillas para que esomy-alist
fuera un símbolo, o fue evaluado aún más como otra cosa. Probablemente desee expandir su pregunta con el nuevo código para que sea más fácil responder.No exactamente defunde pero ¿por qué no? :PAG
fuente
Tengo lo siguiente en mi init:
Es quizás un poco más complejo de lo necesario (especialmente esa evaluación adicional) pero me permite generar las defunciones que necesito para esas propiedades (e incluir cadenas de documentos con la información correcta en las cadenas).
fuente