(Andere haben Ihre direkten Fragen beantwortet tion. Aber das könnte die Frage beantworten, die hinter Ihrer Frage steht, und mit dem sprechen, was Sie wirklich tun wollen. Falls nicht, die anderen Antworten sehen.)
Sie tun nicht brauchen ein Makro überhaupt, zu tun, was Sie wollen. Verwenden Sie einfach defalias
oder fset
. Jeder ist eine Funktion.
(defun foo (cmd &optional search)
(let ((fn (intern (concat "fn-" cmd))))
(defalias fn `(lambda (&optional args)
(let ((str (symbol-name ',fn))
,@(when search
'((dir "~"))))
(message "Called %S from %S" str
(or (and (bound-and-true-p 'dir) dir)
default-directory)))))))
(dolist (x '("f1" "f2")) (foo x))
Dann (symbol-function 'fn-f1)
kehrt:
(lambda (&optional args)
(let ((str (symbol-name 'fn-f1)))
(message "Called %S from %S" str (or (and (bound-and-true-p dir) dir)
default-directory))))
Und wenn Sie verwenden lexikalische Bindung (dSetzen Sie die lokale Variable -*- lexical-binding: t -*-
an den Anfang der Datei, in der dieser Code definiert ist. Dann brauchen Sie kein Backquotting mehr. Zum Beispiel:
(defun foo (cmd &optional search)
(let ((fn (intern (concat "fn-" cmd))))
(defalias fn (lambda (&optional args)
(let ((str (symbol-name fn))
(dir (if search "~" default-directory)))
(message "Called %S from %S" str dir))))))
(dolist (x '("f1" "f2")) (foo x))
Wenn Sie das tun, dann jede Funktion fn-f1
und fn-f2
als Verschluss definiert ist, die wie folgt aussieht:
(symbol-function 'fn-f1)
(closure
((fn . fn-f1)
(search)
(cmd . "f1")
t)
(&optional args)
(let ((str (symbol-name fn))
(dir (if search "~" default-directory)))
(message "Called %S from %S" str dir)))
Und (foo "f3" :SEARCH)
definiert eine Funktion fn-f3
(einen Verschluss), der verkapselt eine Bindung der ansonsten freien Variablen search
an den nicht nil
Wert :SEARCH
, so dass die lokale Variable dir
an "~"
gebunden wird:
(symbol-function 'fn-f3)
(closure
((fn . fn-f3)
(search . :SEARCH) ;; <==============
(cmd . "f3")
t)
(&optional args)
(let ((str (symbol-name fn))
(dir (if search "~" default-directory)))
(message "Called %S from %S" str dir)))