Function 有没有办法获取当前函数的函数名?
我现在这样做:Function 有没有办法获取当前函数的函数名?,function,debugging,emacs,elisp,Function,Debugging,Emacs,Elisp,我现在这样做: (defun foo () (send-to-debug-log "Error. Function terminated." (get-current-function-name))) 硬编码函数名似乎不是一个好的做法。 任何关于实现调用我的获取当前函数名或获取函数名的建议 (defun foo () (send-to-debug-log "Error. Function terminated." 'foo))) (defun foo () (send-t
(defun foo ()
(send-to-debug-log "Error. Function terminated." (get-current-function-name)))
硬编码函数名似乎不是一个好的做法。
任何关于实现调用我的
获取当前函数名
或获取函数名的建议
(defun foo ()
(send-to-debug-log "Error. Function terminated." 'foo)))
(defun foo ()
(send-to-debug-log "Error. Function terminated." (nth 1 (backtrace-frame 2))))
如果你把它叫做lambda,你就得到了整个lambda。它与apply
、funcall
和eval
一起工作
我认为最简单、最健壮的方法就是像现在这样显式地编写函数名。您可以尝试以下方法:
(defun calling-function ()
(let ((n 6) ;; nestings in this function + 1 to get out of it
func
bt)
(while (and (setq bt (backtrace-frame n))
(not func))
(setq n (1+ n)
func (and bt
(nth 0 bt)
(nth 1 bt))))
func))
使用包哪个函数模式
(在melpa中),您可以通过编程方式调用该函数
(defconst my-defun-macros '(defun cl-defun defmacro cl-defmacro))
(defun my-add-defun-name (orig-fun name &rest args)
(let* ((my-current-defun-name (if (consp name) (cadr name) name))
(macroexpand-all-environment
(cons (cons 'my-get-current-function-name
(lambda () my-current-defun-name))
macroexpand-all-environment))
(code (apply orig-fun name args)))
(macroexpand-all code macroexpand-all-environment)))
(defmacro my-get-current-function-name ()
"Return current defun's name.
Only works within the advised macros in `my-defun-macros'."
(error "my-get-current-function-name used outside of a defun"))
(dolist (m my-defun-macros)
(advice-add m :around #'my-add-defun-name))
更多信息:
这并不比硬编码函数名更好。您提供的函数返回发送到调试日志
。要获取foo
,需要将其更改为(回溯帧3)
。换言之,此函数依赖于包含它的其他函数,因此不灵活。您可以编写一个函数,该函数返回到回溯中,直到找到正确的名称。我只是想告诉你该用什么。我在Tramp中应用了类似的技术,请参见Tramp调试消息
。我明白了。将其放入foo
,而应放入send to debug log
。回溯步骤应始终保持不变。如果对代码进行字节编译,回溯的形状会有所不同,因此要使其“可靠”工作可能相当棘手。@Stefan是对的。它在未编译时返回正确的函数名。编译后,它以交互方式返回调用
。您可以尝试使用回溯帧
,但我认为更好的解决方案是在宏扩展期间(即编译时)将(获取当前函数名)
替换为函数名。它不仅效率更高,而且还可以处理诸如用作回调的lambda函数之类的情况(在这种情况下,englobing函数可能根本不存在于回溯中)。因此,我强烈建议您M-x报告emas bug
,并请求将其作为一项功能。(但是一个打字错误:报告emacs bug
),在很难理解这一点之后。我有两个问题。是否应将(code(apply orig fun name args))
更改为(code(apply orig fun my current defun name args))
。为defun添加建议对我来说也是一个新概念。它是否适用于从其他程序包和其他编译的程序包defun
。至于第二个,它影响了defun
的所有用法,因此它非常具有侵入性。我觉得在这一点上有些不对劲。由于advice add
是在运行时完成的,因此my add defun name
也必须在运行时完成,宏扩展也是如此。这种方法还增加了所有不相关的defun
的开销。它在效率方面失去了优势?就性能而言,我认为您永远不会注意到其中的差异:它只会影响宏扩展,即编译文件的时间或加载未编译文件的时间。在那之后,defun
基本上再也看不到了。它在complie之后就不起作用了。哪个函数
使用当前缓冲区的查找函数定义。
(Which-function)