Используйте строковую переменную в качестве аргумента макроса
Я хочу этот код:
(setq name "foobar")
(defun (intern name) ())
сделать то же самое, что и:
(defun foobar ())
Я пробовал это (из этого вопроса):
(defmacro make-my-function (name)
(list 'defun
(intern (format "my-%s-function" name)) ()
(list 'interactive)
'(message "It's work !")))
Но я получаю функцию my-name-function, но мне нужна my-foobar-function. Моя цель - определить второстепенные режимы из списка клавиш.
Спасибо
2 ответа
Ваш макрос работает нормально. Как вы пытались вызвать его? Вы должны вызывать так: (make-my-function foo)
, затем M-: (symbol-function 'my-foo-function)
показывает определение функции:
(lambda nil
(interactive)
(message "It's work !"))
Причина, по которой ваша первоначальная попытка до определения макроса не сработала, заключается в том, что defun
является макросом - он не оценивает свои аргументы. Так (defun (intern name) ())
синтаксически неверно: defun
нужен символ в качестве первого аргумента, и (intern name)
это список, а не символ.
Обновлено, после вашего комментария -
Ваш вопрос совершенно неясен. Теперь звучит так, как будто вы хотите позвонить (make-my-function foo)
в контексте, где у вас есть переменная my-foo-function
, чье значение является строкой.
Если это так, то используйте это:
(defmacro make-my-function (name)
(list 'defun
(intern (symbol-value (intern (format "my-%s-function" name))))
()
(list 'interactive)
'(message "It's work !")))
(setq my-foo-function "toto")
(make-my-function foo)
Я не могу представить такой вариант использования, но подозреваю, что это тоже не то, что вы пытаетесь сделать. Похоже, вы не указали хорошо, что такое требуемое поведение.
Я не могу воссоздать вашу проблему с вашим make-my-function
макрос, но попробуйте с обратной цитатой:
(defmacro make-my-function (name)
`(defun ,(intern (format "my-%s-function" name)) ()
'interactive
'(message "It works!")))