Je travaille à l' optimisation de ma configuration emacs où je peux créer dynamiquement des fonctions interactives pour tous les thèmes que j'ai dans une liste.
Voici une version simplifiée de la construction que j'essaie de faire fonctionner.
;; 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))
Mais si je déroule la boucle manuellement, cela fonctionne:
;; WORKS
(my/create-defun zz-abc)
(my/create-defun zz-def)
(my/create-defun zz-ghi)
Mais ce qui suit ne fonctionne pas là où je passe les noms de symboles (ce qui se produit probablement lorsque la boucle se déroule d'elle-même). Notez les guillemets avant les arguments de macro.
;; DOES *NOT* WORK
(my/create-defun 'zz-abc)
(my/create-defun 'zz-def)
(my/create-defun 'zz-ghi)
Mise à jour
Grâce à l 'aide de @wvxvw , j'ai finalement réussi à faire en sorte que cela fonctionne !
Comme le suggère @wvxvw, je ne produirai pas de défuns générant des lots pour tous les cas d'utilisation. C'était un cas d'utilisation spécial où pour un thème nommé XYZ
, je veux générer un defun appelé load-theme/XYZ
qui fait le travail de
- Désactiver tous les autres thèmes qui pourraient être actifs
- Appel
load-theme
àXYZ
- Faire des trucs plus personnalisés liés à ce thème; Je passe les paramètres personnalisés pour chaque thème à travers la liste
my/themes
.
la source
defuns
intérieur aprogn
.progn
est autorisé à être un formulaire de niveau supérieur (dans le sens où tout ce qui s'applique aux formulaires de niveau supérieur s'applique également au contenu deprogn
). Mais je remettrais en question la justification de la création de fonctions de cette manière: pourquoi ne pas avoir, disons, un has-table avec des lambdas comme valeurs?cons
liste ne contient que des es, mais je prévois de les convertir en listes avec des propriétés personnalisées pour chaque thème.(my/create-defun name)
3 fois, vous devez donc définir une fonction appeléename
3 fois.Réponses:
Voici une tentative d'explication et quelques suggestions.
Maintenant, essayons de résoudre ce problème:
Exemple de lecture de noms de fonction à partir d'une variable
Le problème était d'ordre conceptuel: les macros sont destinées à générer du code lorsque l'environnement veut le lire. Lorsque vous exécutez le code vous-même (en tant qu'utilisateur de votre programme), il est déjà trop tard pour le faire (l'environnement devrait alors savoir ce qu'est le programme).
Une note marginale: je déconseille de regrouper plusieurs
defuns
. La raison en est que cela rend le débogage beaucoup plus compliqué. Le peu de redondance que vous avez dans les définitions répétées est très rentable pendant la phase de maintenance (et la maintenance est généralement la phase la plus longue de la durée de vie du programme).la source
mapcar
trouverai à utiliser avec des listes. Cela ne semble pas fonctionner avec mon cas d'utilisation réel. Je creuserai cela dès que possible.(mapcar (lambda (x) (message "argument: %s" x)) some-alist)
pour voir quel est l'argument que vous obtenez, et travailler à partir de là. Si c'est une liste associative, j'imagine que la sortie ressemble à quelque choseargument: (foo . bar)
, alors vous pourriez accéder à l'foo
aidecar
et à l'bar
utilisation descdr
fonctions.nth
fn au lieu decar
etcadr
) mais l'sequencep
enregistrement a étémapcar
erroné. Je fournissais une liste en entrée, mais mapcar ne pensait pas que c'était une séquence. Si je le faisais(sequencep my-alist)
, ce n'était pas nul. Je suis donc confus .. Je dois encore déboguer cela.my-alist
étaitnil
ou vous avez oublié (ou ajouté des guillemets supplémentaires) de sorte quemy-alist
c'était soit un symbole, soit encore évalué pour être autre chose. Vous souhaiterez probablement étendre votre question avec le nouveau code pour faciliter la réponse.Pas exactement désamorcé mais pourquoi pas? : P
la source
J'ai les éléments suivants dans mon init:
Il est peut-être légèrement plus complexe que nécessaire (en particulier cet eval supplémentaire), mais il me permet de générer les défuns dont j'ai besoin pour ces propriétés (et d'inclure des docstrings avec les informations correctes dans les chaînes).
la source