nadvice는 어떻게 사용합니까?


29

내 구성은 충고로 가득 차 있으며 새로운 반짝이는 미니멀리스트 nadvice.el패키지에 대해 계속 듣고 있습니다.

매뉴얼을 검색했으며 소스를 읽었 지만 공개적으로 인정 합니다. 실제로 실제로 어떻게 사용하는지 전혀 모릅니다.

여기 누구든지 나를 안내해 주거나 구식 조언을 포팅하는 방법을 알려줄 수 있습니까?


7
질문에 +1 매뉴얼을 검색했지만 필요한 것을 찾지 못한 경우 (doc) 버그 보고서를 제출하십시오 M-x report-emacs-bug. 일부 개발자는 때때로 문서화보다 개발을 선호합니다. ;-) Emacs 자체를 문서화하는 것이 중요합니다.
Drew

2
매뉴얼에는 실제로 섹션이 있습니다 (info "(elisp) 이전 조언 포팅")을 참조하십시오 . 어떤 이유로 든 자세한 색인에 나열되어 있지 않습니다.
wasamasa 2016 년


3
사용하는 몇 가지 예 nadvice내 설정에서 : : 후 , : 필터 복귀 , : 주위 , : 전-까지
Kaushal 모디

1
@wasamasa 나는 섹션이 완전하지 않다는 것을 두려워한다. 더 복잡한 몇 가지 조언 (아마도 하나만 볼 것입니다)이 있습니다. 여기서 각각에 대해 질문을해야합니까?
PythonNut

답변:


22

C-h f add-function의 기본 메커니즘을 설명하는 필요한 모든 정보가 포함되어 advice-add있습니다.

새로운 어드바이스 시스템은 기본적으로 인수 C-h f add-function의 선택에 따라 표에 설명 된 함수로 함수의 현재 정의를 바꾸는 것과 같이 WHERE작동합니다. 소스 파일에서 어떤 동작이 정의되었는지 추적하기 위해서만 깔끔합니다.

:around옵션이 있는 예

가장 일반적인 경우는 :around옵션이므로 이에 대한 예를 들어 보겠습니다. WHERE가능한 경우 전용 매개 변수 를 사용하는 것이 좋지만 동등한 :around기능으로 서로를 대체 할 수 있습니다 .

예를 들어, 사용을 디버깅하고 호출 될 때마다 인수 목록을 find-file 원한다고 가정합니다 print. 당신은 쓸 수 있습니다

(defun my-find-file-advice-print-arguments (old-function &rest arguments)
  "Print the argument list every time the advised function is called."
  (print arguments)
  (apply old-function arguments))

(advice-add #'find-file :around #'my-find-file-advice-print-arguments)

이 새로운 구현을 통해 조언에 필요한 모든 것이 인수로 전달됩니다. ad-get-args인수는 일반 함수 인수 (상당한 인수의 경우)로서 advice 함수에 전달되기 때문에 불필요해진다 WHERE. 조언이 함수와 인수를 인수 ad-do-it:around얻을 때 불필요 해 지므로 (ad-do-it)양식으로 대체됩니다.

(apply old-function arguments)

또는 당신이 인수의 이름을 지었을 때

(funcall old-function first-arg second-arg)

마법 형태가 없기 때문에 더 깨끗합니다. 인수를 수정하면 수정 된 값을에 전달하면됩니다 OLD-FUNCTION.

다른 WHERE값들

의 docstring add-function에는 모든 조언 장소 (또는 "콤비 네이터")의 표와 이들이 동등한 내용이 있으며 lambda, 권고 된 기능과 동등한 동작 측면에서 기능을 설명합니다 .

`:before'       (lambda (&rest r) (apply FUNCTION r) (apply OLDFUN r))
`:after'        (lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
`:around'       (lambda (&rest r) (apply FUNCTION OLDFUN r))
`:override'     (lambda (&rest r) (apply FUNCTION r))
`:before-while' (lambda (&rest r) (and (apply FUNCTION r) (apply OLDFUN r)))
`:before-until' (lambda (&rest r) (or  (apply FUNCTION r) (apply OLDFUN r)))
`:after-while'  (lambda (&rest r) (and (apply OLDFUN r) (apply FUNCTION r)))
`:after-until'  (lambda (&rest r) (or  (apply OLDFUN r) (apply FUNCTION r)))
`:filter-args'  (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
`:filter-return'(lambda (&rest r) (funcall FUNCTION (apply OLDFUN r)))

(cited from `C-h f add-function')

여기서 FUNCTION은 조언 기능이고 OLDFUN은 조언이 추가되는 기능입니다. 한 번에 모든 내용을 이해하려고 시도하지 말고 WHERE적절한 소리가 나는 기호를 선택하고 이해하십시오.

또는 그냥 사용하십시오 :around. 지금까지 내가 전문 사용하는 유일한 장점 말할 수있는 WHERE이상들 :around모든 것을 당신이 찾는에서 좀 더 정보를 얻을 수 있다는 것입니다 C-h f ADVISED-FUNCTION 전에 조언을 문서화 문자열을 읽는합니다. 조언이 포함 된 코드를 게시 할 계획이 아니라면 중요하지 않을 것입니다.

명명 된 조언 기능

명명 된 함수를 조언으로 사용하는 것이 좋습니다. 많은 이점이 있습니다 (일부 기능은 후크에 명명 된 함수를 사용하는 경우에도 적용됨).

  • 로 표시 C-h f find-file됩니다

    :around advice: `my-find-file-advice-print-arguments'
    

    advice 함수의 정의에 링크. 보통 함수가 정의 된 파일에 대한 링크를 포함한다. 조언이 lambda양식에서 직접 양식 으로 정의 된 advice-add 경우 docstring은 인라인으로 표시되며 (긴 docstring의 혼란?) 어디에 정의되었는지는 표시하지 않습니다.

  • 당신은 조언을 제거 할 수 있습니다

    (advice-remove #'find-file #'my-find-file-advice-print-arguments)
    
  • advice-add이전 버전을 활성 상태로 유지하거나 다시 실행할 위험 없이 조언 정의를 업데이트 할 수 있습니다 ( advice-add변경된 상태 로 실행하면 이전 lambda조언에 대한 업데이트가 아닌 새로운 조언으로 인식됨).

측면 설명#'function표기법은 'function바이트 컴파일러가 심볼을 함수 이름으로 식별하여 누락 된 함수 (예 : 오타로 인해)를 식별하는 데 도움이된다는 점을 제외하면 기본적으로와 동일합니다 .


당으로 논의 나는 그것을해야합니다 .. 해시 따옴표는 모든 인수 여기에 사용해서는 안 스티븐 모니로했다 (advice-add 'find-file :around #'my-find-file-advice-print-arguments)유사 (advice-remove 'find-file #'my-find-file-advice-print-arguments).
Kaushal Modi

advice-add국경 사건 이라고 생각 합니다. 개인적으로 나는 ' ↔ #'구별을 대부분 함수 이름의 오타를 식별하는 데 도움이된다고 생각하므로, 조언이 추가 될 때 함수가 정의 될지 여부에 따라 달라질 것입니다.
kdb

@kdb 나는 결국이 문서를 찾았다 add-function. 문서가 더 명확 해지기를 바랍니다. 나는 그것을 위해 패치를 만드는 것을 볼 수 있습니다.
PythonNut

@kdb 당신은 그것은에 표시 "의미합니까 C-h f find-file하지 C-x?
Peeja

@Peeja 예, 수정했습니다.
kdb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.