어휘 바인딩이있는 let 내부의 defun은 바이트 컴파일 경고를 제공합니다. "함수가 정의되어 있지 않습니다"


13

defun내부 let어휘 바인딩을 사용하여 클로저를 작성 하여 정적 변수의 효과를 얻고 싶습니다 . 그러나 파일을 바이트 컴파일 할 때 경고 메시지가 나타납니다. 내가 잘못하고 있거나 그렇지 않은 경우이 경고를 억제하는 방법이 있습니까?

MCVE를 만들었습니다.

;; -*- lexical-binding: t -*-

(let ((count 0))
  (defun increase-count ()
    (interactive)
    (setq count (1+ count))
    (message "Count is: %d" count))

  ;; The warning happens here.
  (increase-count))

코드는 예상대로 작동합니다.이 함수 increase-count는 "Count is : n"을 출력합니다. 여기서 n은 호출 될 때마다 증가합니다. 그러나이 파일을 바이트 컴파일 할 때 다음 경고가 나타납니다.

In end of data:
mcve.el:11:1:Warning: the function ‘increase-count’ is not known to be
    defined.

increase-countlet-block의 끝에서 호출되기 전에 항상 정의되어야 하는 것 같습니다 . 그렇지 않습니까?


defun생각하는대로하지 않고 항상 최상위 수준의 정의를 만듭니다. Elisp는 결국 계획이 아닙니다 ...
wasamasa

2
나는 그것이 최상위 정의를 만든다는 것을 알고있다. 그것이 내가 원하는 것입니다. 그 최상위 수준 정의가 클로저가 되길 원합니다. 이 바이트 컴파일 경고를 제외하고 원하는 방식으로 작동하는 것 같습니다.
Will Kunkel

답변:


7

함수가 정의 될지 여부를 결정하는 바이트 컴파일러의 방법은 매우 "순진"하며 "명백한"경우에도 속지 않습니다. 그러나 컴파일러에서 발생하는 상황을 이해할 수있는 방식으로 작성할 수 있습니다.

(defalias 'increase-count
  (let ((count 0))
    (lambda ()
      (interactive)
      (setq count (1+ count))
      (message "Count is: %d" count))))

물론 바이트-컴파일러의 로직을 개선하는 것이 더 좋습니다. 패치는이를 환영합니다.


5

바이트 컴파일러 경고를 표시하지 않으려면 0 열 (가장 왼쪽)에서 시작하여 코드 앞에 이것을 추가하십시오.

(declare-function increase-count "your-file-name.el")

C-h f declare-function 알려줍니다 :

declare-function의 Lisp 매크로입니다 subr.el.

(declare-function FN FILE &optional ARGLIST FILEONLY)

바이트 컴파일러에 함수 FN가 정의되어 있음을 알리십시오 FILE. 이 FILE인수는 바이트 컴파일러가 아니라 check-declareFILE에 대한 정의가 포함되어 있는지 확인하는 패키지에서 사용됩니다 FN.

FILELisp 파일 (이 경우 ".el" 확장명은 선택 사항 임) 또는 C 파일 일 수 있습니다. C 파일은 Emacs "src/"디렉토리를 기준으로 확장 됩니다. 리스프 파일은을 사용하여 검색되며 locate-library, 실패하면 선언이 포함 된 파일의 위치를 ​​기준으로 확장됩니다. FILE"ext:"접두사는 외부 파일입니다. check-declare이러한 파일이 발견되면 확인하고, 파일이 없으면 오류없이 건너 뜁니다.

선택 ARGLISTFN의 인수 t를 지정 하거나 FN의 인수를 지정하지 않습니다 . 생략 된 ARGLIST기본값은 t없습니다, nil하십시오 nil ARGLIST빈 인수 목록을 지정하고, 명시 적으로는 t ARGLIST나중에 인수를 공급 허용하는 자리 표시 자입니다.

옵션 FILEONLY이외의 nil수단 check-declare만 확인합니다 FILE그것을 정의하지 않는 것이 존재 FN. check-declare예를 들어, 인식하지 못하는 함수 정의를위한 것입니다 defstruct.

의 목적을 check-declare위해이 문장은 줄의 첫 번째 공백이 아니어야합니다.

자세한 정보는 정보 노드를 참조하십시오 (elisp)Declaring Functions.


당면한 FILEONLY사건에 대해 논- 논의 주장이 필요한가? BTW, 나는 같은 대답을 주었을 것이다 ;-).
Tobias

@ Tobias : FILEONLY여기에는 필요하지 않은 것 같습니다. 어느 것이 및 defuns 를 check-declare인식 한다는 것을 나타내는 것 같습니다 . fg
Drew

@ 드류, 나는에 대한 마지막 코멘트를 생각 f하고 g단지의 맥락에서 의미가 emacs.stackexchange.com/q/39439 ?
phils

@ phils : 예, 나는 이것을 말하려고했습니다 FILEONLY. 나에게는 여기에 필요하지 않은 것 같습니다. 그것은 그것이 defun 을 check-declare인정 한다는 것을 나타내는 것 같습니다 increase-count. ;-)
Drew

3

나는 내 문제의 정의를 배치 믿고 eval-and-compile또한 것이다 피상적 스테판의에서와 동일한 결과를 얻을 정답 :

(eval-and-compile
  (let ((count 0))
    (defun increase-count ()
      (interactive)
      (setq count (1+ count))
      (message "Count is: %d" count))))

그러나 나는 사용의 미묘함에 거의 익숙 eval-and-compile하지 않으며,이 접근법이 어떤 식 으로든 우월하다고 기대하지 않습니다.

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