편집 : 최근 Emacs 에서이 작업을 수행하는 더 좋은 방법 은 인수 수를 확인하기 위해 컴파일러 매크로 를 정의하는 것 입니다. 일반적인 매크로를 사용하여 내 원래의 대답은 다음과 보존되지만가 기능을 전달하는 것을 방해하지 않기 때문에 컴파일러 매크로는 우수 funcall또는 apply런타임에.
최신 버전의 Emacs에서는 인수 수를 확인하고 일치하지 않는 경우 경고 (또는 오류)를 생성하는 함수에 컴파일러-매크로를 정의하여이를 수행 할 수 있습니다. 유일한 미묘한 점은 컴파일러 매크로가 평가 또는 컴파일을 위해 원래 함수 호출 양식을 변경하지 않고 반환해야한다는 것입니다. &whole인수 를 사용하여 값을 반환하면됩니다. 이것은 다음과 같이 달성 될 수 있습니다 :
(require 'cl-lib)
(defun my-caller (&rest args)
(while args
(message "%S %S" (pop args) (pop args))))
(define-compiler-macro my-caller (&whole form &rest args)
(when (not (cl-evenp (length args)))
(byte-compile-warn "`my-caller' requires an even number of arguments"))
form)
(my-caller 1 2 3 4)
(my-caller 1 2)
(funcall #'my-caller 1 2 3 4) ; ok
(apply #'my-caller '(1 2)) ; also ok
(my-caller 1) ; produces a warning
(funcall #'my-caller 1 2 3) ; no warning!
(apply #'my-caller '(1 2 3)) ; also no warning
주 funcall및 apply컴파일러 매크로에 의해 인수 검사를 건너 뛸 지금 사용할 수 있지만. 이름에도 불구하고, 컴파일러 매크로도를 통해 평가 '해석'의 과정에서 확장하는 것 C-xC-e, M-xeval-buffer당신이 평가에뿐만 아니라,이 예제를 컴파일에 오류를 얻을 수 있도록.
원래 답변은 다음과 같습니다.
다음은 "확장시 경고를 제공하는 매크로를 사용하는"Jordon의 제안을 구현하는 방법입니다. 매우 쉬운 것으로 밝혀졌습니다.
(require 'cl-lib)
(defmacro my-caller (&rest args)
(if (cl-evenp (length args))
`(my-caller--function ,@args)
(error "Function `my-caller' requires an even number of arguments")))
(defun my-caller--function (&rest args)
;; function body goes here
args)
(my-caller 1 2 3 4)
(my-caller 1 2 3)
위의 파일을 컴파일하려고 시도 .elc하면 컴파일 로그에 클릭 가능한 멋진 오류 메시지와 함께 실패합니다 ( 파일이 생성 되지 않음 ).
test.el:14:1:Error: `my-caller' requires an even number of arguments
또한 대체 할 수 (error …)와 함께 (byte-compile-warn …)컴파일을 계속 할 수 있도록하는 대신 오류의 경고를 생성합니다. (댓글로 지적 해 주신 Jordon에게 감사드립니다).
컴파일시 매크로가 확장되므로이 검사와 관련된 런타임 패널티가 없습니다. 물론 다른 사람이 my-caller--function직접 전화하는 것을 막을 수는 없지만 적어도 이중 하이픈 규칙을 사용하여 "개인"기능으로 광고 할 수 있습니다.
이 목적으로 매크로를 사용할 때 주목할만한 단점my-caller 은 더 이상 일류 함수가 아니라는 것입니다. funcall즉 apply, 런타임 에 또는 런타임에 전달할 수 없습니다 (또는 적어도 예상 한대로 수행하지는 않습니다). 그런 점 에서이 솔루션은 실제 함수에 대한 컴파일러 경고를 단순히 선언 할 수있는 것만 큼 좋지 않습니다. 물론 사용 apply하면 어쨌든 컴파일 타임에 함수에 전달되는 인수 수를 확인할 수 없으므로 허용되는 절충입니다.