Chcę uzyskać efekt zmiennej statycznej, używając defun
wewnątrz let
z leksykalnym wiązaniem do utworzenia zamknięcia. Jednak podczas kompilacji bajtowej pliku pojawia się ostrzeżenie. Czy robię coś złego, a jeśli nie, czy istnieje sposób na stłumienie tego ostrzeżenia?
Stworzyłem 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))
Kod działa zgodnie z oczekiwaniami: funkcja wyświetla increase-count
„Count is: n”, gdzie n zwiększa się za każdym razem, gdy jest wywoływane. Jednak podczas kompilacji bajtowej tego pliku pojawia się następujące ostrzeżenie:
In end of data:
mcve.el:11:1:Warning: the function ‘increase-count’ is not known to be
defined.
Wydaje mi się, że increase-count
należy to zawsze zdefiniować, zanim zostanie wywołane na końcu let-block. Czy tak nie jest?
byte-compilation
lexical-scoping
defun
lexical-binding
Will Kunkel
źródło
źródło
defun
nie robi tego, co myślisz, zawsze tworzy definicję najwyższego poziomu. W końcu Elisp nie jest Schematem ...Odpowiedzi:
Sposób kompilatora bajtów decydujący o tym, czy funkcja zostanie zdefiniowana, jest bardzo „naiwny” i daje się zwieść nawet w „oczywistym” przypadku. Ale możesz napisać to w sposób, który pozwoli kompilatorowi zrozumieć, co się dzieje:
Oczywiście jeszcze lepszym rozwiązaniem byłoby usprawnienie logiki kompilatora bajtów: mile widziane łatki.
źródło
Aby pominąć ostrzeżenie kompilatora bajtów, spróbuj dodać to przed kodem, zaczynając od kolumny 0 (skrajnie po lewej):
C-h f declare-function
mówi ci:źródło
FILEONLY
przedmiotowej sprawie niezbędny jest argument inny niż zero ? BTW, dałbym tę samą odpowiedź ;-).FILEONLY
Wydaje mi się, że tutaj nie był potrzebny. Co wydaje się wskazywać, żecheck-declare
rozpoznajef
ig
odrzuca.f
ig
ma sens tylko w kontekście emacs.stackexchange.com/q/39439 ?FILEONLY
nie wydawało mi się to potrzebne tutaj. Co wydaje się wskazywać, żecheck-declare
rozpoznajeincrease-count
przegraną. ;-)Sądzę, że umieszczenie omawianej definicji w ten sposób
eval-and-compile
mogłoby pozornie osiągnąć ten sam wynik, co w poprawnej odpowiedzi Stefana :Jednak ledwo znam subtelności korzystania,
eval-and-compile
a ponadto nie oczekuję, że takie podejście będzie w jakikolwiek sposób lepsze.źródło