Я работаю над оптимизацией своего конфига emacs, где я могу динамически создавать интерактивные функции для всех тем, которые есть в списке.
Ниже приведен упрощенный вариант конструкции, которую я пытаюсь заставить работать.
;; 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))
Но если я разверну цикл вручную, он будет работать:
;; WORKS
(my/create-defun zz-abc)
(my/create-defun zz-def)
(my/create-defun zz-ghi)
Но ниже не работает, где я передаю имена символов (что, вероятно, происходит, когда цикл разворачивается сам по себе). Обратите внимание на кавычки перед аргументами макроса.
;; DOES *NOT* WORK
(my/create-defun 'zz-abc)
(my/create-defun 'zz-def)
(my/create-defun 'zz-ghi)
Обновить
Благодаря помощи @wvxvw , я наконец-то заработал !
Как подсказывает @wvxvw, я не буду генерировать пакетные функции для любого и каждого варианта использования. Это был особый случай, когда для темы с именем XYZ
я хочу создать defun с именем, load-theme/XYZ
который выполняет работу
- Отключение всех других тем, которые могут быть активными
- Призывая
load-theme
кXYZ
- Делать еще кое-что, связанное с этой темой; Я передаю пользовательские настройки для каждой темы через
my/themes
alist.
elisp-macros
Каушал Моди
источник
источник
defuns
внутрьprogn
.progn
разрешено быть формой верхнего уровня (в том смысле, что все, что относится к формам верхнего уровня, относится и к содержимомуprogn
). Но я бы поставил под сомнение обоснованность создания функций таким образом: почему бы не иметь, скажем, таблицу с лямбдами в качестве значений?cons
es, но я планирую преобразовать их в списки с настраиваемыми свойствами для каждой темы.(my/create-defun name)
3 раза, поэтому вам следует определить функцию, вызываемуюname
3 раза.Ответы:
Вот попытка объяснения и некоторые предположения.
Теперь давайте попробуем исправить это:
Пример с чтением имен функций из переменной
Проблема была концептуальной: макросы предназначены для генерации кода, когда среда хочет его прочитать. Когда вы выполняете код самостоятельно (как пользователь вашей программы), уже слишком поздно делать это (к тому времени среда должна знать, что это за программа).
Заметка на полях: я бы посоветовал не смешивать несколько
defuns
. Причина в том, что это делает отладку намного сложнее. Небольшая избыточность, которую вы имеете в повторяющихся определениях, очень хорошо окупается во время фазы обслуживания (а обслуживание, как правило, является самой длинной фазой в жизни программы).источник
mapcar
с alists. Это не похоже на мой фактический вариант использования. Я буду копаться в этом, как только смогу.(mapcar (lambda (x) (message "argument: %s" x)) some-alist)
какой аргумент вы получите, и поработать оттуда. Если это ассоциативный список, я мог бы представить что-то вроде выводаargument: (foo . bar)
, тогда вы можете получить доступ кfoo
использованиюcar
иbar
использованиюcdr
функций.nth
fn вместоcar
иcadr
), ноsequencep
зарегистрировался сmapcar
ошибкой. Я предоставлял alist в качестве входных данных, но все же mapcar не думал, что это последовательность. Если бы я сделал(sequencep my-alist)
, это было не ноль. Так что я в замешательстве .. Я должен все же отладить это.my-alist
былиnil
или вы забыли (или добавили лишние) кавычки, чтобы ониmy-alist
были либо символом, либо оценивались еще дальше как нечто иное. Возможно, вы захотите дополнить свой вопрос новым кодом, чтобы на него было легче ответить.Не совсем так, но почему бы и нет? :П
источник
У меня есть следующее в моем init:
Возможно, он немного сложнее, чем нужно (особенно это дополнительный eval), но он позволяет мне генерировать необходимые для этих свойств определения функций (и включать строки строк с правильной информацией в строках).
источник