C에는 __func__
현재 함수 이름을 보유하는 매직 변수 가 있습니다. Bash FUNCNAME
에는 호출 스택의 모든 함수 이름을 보유 하는 배열 이 있습니다 !!!
Emacs Lisp에도 비슷한 것이 있습니까? 또는 함수가 이름에 액세스 할 수있는 간단한 방법은 무엇입니까?
Emacs Lisp 매뉴얼 (12 장 함수 또는 변수 및 함수 색인 및 ..)에서 답을 찾지 못했습니다.
C에는 __func__
현재 함수 이름을 보유하는 매직 변수 가 있습니다. Bash FUNCNAME
에는 호출 스택의 모든 함수 이름을 보유 하는 배열 이 있습니다 !!!
Emacs Lisp에도 비슷한 것이 있습니까? 또는 함수가 이름에 액세스 할 수있는 간단한 방법은 무엇입니까?
Emacs Lisp 매뉴얼 (12 장 함수 또는 변수 및 함수 색인 및 ..)에서 답을 찾지 못했습니다.
답변:
대화식 기능 (예 : 명령)의 경우 변수 this-command
또는보다 안전한 변수를 사용할 수 있습니다 real-this-command
. 차이점은 자체 함수를 작성할 때의 값을 명시 적으로 변경할 수 있다는 것입니다 this-command
. 대부분 이것은 last-command
반복 명령 과 관련된 트릭을 재생하기 위해 수행됩니다 . 당신은 이것을 할 수 없습니다 real-this-command
. 항상 현재 명령의 이름이됩니다.
비 대화식 기능과 동등한 기능을 알지 못합니다.
this-command
하며 real-last-command
전혀 같지 않습니다 __func__
. 예를 들어, 명령 A가 명령 B를 호출하면 명령 B가 인쇄 this-command
되지 않고 명령 A가 인쇄됩니다.이 기능도 전혀 작동하지 않습니다.
: 나는 거기에 더 나은 성능을 제공하는 확장에 대신 런타임의 / 컴파일 시간이 할 수있는 방법이 될 나는 마침내 오늘이 질문에 대한 내 대답에서 작업하는 동안 것을 구현 수 있음을 내 원래 대답했다 내가 있던 기능을 확인하는 방법 스택에서 대화식으로 호출?
모든 현재 역 추적 프레임을 생성하는 함수는 다음과 같습니다.
(defun call-stack ()
"Return the current call stack frames."
(let ((frames)
(frame)
(index 5))
(while (setq frame (backtrace-frame index))
(push frame frames)
(incf index))
(remove-if-not 'car frames)))
매크로에서이를 사용하여 확장 스택을 조회하여 당시에 어떤 함수 정의가 확장되는지 확인하고 해당 값을 코드에 바로 넣을 수 있습니다.
확장을 수행하는 기능은 다음과 같습니다.
(defmacro compile-time-function-name ()
"Get the name of calling function at expansion time."
(symbol-name
(cadadr
(third
(find-if (lambda (frame) (ignore-errors (equal (car (third frame)) 'defalias)))
(reverse (call-stack)))))))
여기에 작동합니다.
(defun my-test-function ()
(message "This function is named '%s'" (compile-time-function-name)))
(symbol-function 'my-test-function)
;; you can see the function body contains the name, not a lookup
(lambda nil (message "This function is named '%s'" "my-test-function"))
(my-test-function)
;; results in:
"This function is named 'my-test-function'"
당신이 사용할 수있는 backtrace-frame
당신이 직접 함수 호출을 나타내는 프레임을보고 그에서 이름을 얻을 때까지 스택을 조회 할 수 있습니다.
(defun get-current-func-name ()
"Get the symbol of the function this function is called from."
;; 5 is the magic number that makes us look
;; above this function
(let* ((index 5)
(frame (backtrace-frame index)))
;; from what I can tell, top level function call frames
;; start with t and the second value is the symbol of the function
(while (not (equal t (first frame)))
(setq frame (backtrace-frame (incf index))))
(second frame)))
(defun my-function ()
;; here's the call inside my-function
(when t (progn (or (and (get-current-func-name))))))
(defun my-other-function ()
;; we should expect the return value of this function
;; to be the return value of my-function which is the
;; symbol my-function
(my-function))
(my-other-function) ;; => 'my-function
여기서는 런타임에서 함수 이름 조회를 수행하고 있지만 반복 호출 및 컴파일 된 elisp에 더 성능이 좋은 함수 기호로 직접 확장되는 매크로에서 이것을 구현하는 것이 가능할 수도 있습니다.
불완전한 형태로 여기에서 찾을 수있는 elisp에 대한 일종의 함수 호출 로거를 작성하는 동안이 정보를 찾았지만 유용 할 수 있습니다. https://github.com/jordonbiondo/call-log
defun
으로 둘러싸인 eval-and-compile
즉, 그것은 반환 nil
.