편집 : 최근 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
하면 어쨌든 컴파일 타임에 함수에 전달되는 인수 수를 확인할 수 없으므로 허용되는 절충입니다.