İçerideki Defun, lexical ciltleme ile bayt-derleme uyarısı verir, “fonksiyonun tanımlandığı bilinmemektedir”


13

Ben kullanarak statik değişkenin etkisini almak istiyorum defuniçeride ait letsözcük bir kapatma oluşturmak için bağlayıcı ile. Ancak, dosyayı bayt derlerken bir uyarı alıyorum. Yanlış bir şey mi yapıyorum, yoksa bu uyarıyı bastırmanın bir yolu var mı?

Bir MCVE oluşturdum:

;; -*- 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 beklendiği gibi çalışır: işlev increase-count"Count is: n" çıktısını alır ve burada her çağrıldığında n artar. Ancak, bu dosyayı bayt derlerken, aşağıdaki uyarıyı alıyorum:

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

Bana öyle geliyor ki increase-count, her zaman izin bloğunun sonunda çağrılmadan önce tanımlanmalıdır. Durum böyle değil mi?


defundüşündüğünüzü yapmaz, her zaman üst düzey bir tanım oluşturur. Elisp sonuçta Şema değil ...
wasamasa

2
Üst düzey bir tanım oluşturduğunun farkındayım; istediğim bu. Sadece üst düzey tanımın bir kapanış olmasını istiyorum. Bu bayt derleme uyarısı dışında istediğim gibi çalışıyor gibi görünüyor.
Kunkel

Yanıtlar:


7

Bayt-derleyicinin bir işlevin tanımlanıp tanımlanmayacağına karar verme şekli çok "saf" ve "açık" durumunuzda bile kandırılıyor. Ancak derleyicinin ne olduğunu anlamasını sağlayacak şekilde yazabilirsiniz:

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

Tabii ki, daha da iyisi bayt-derleyicinin mantığını geliştirmek olacaktır: yamalar bunun için hoş geldiniz.


5

Bayt derleyici uyarısını bastırmak için, 0 sütunundan (en solda) başlayarak kodunuzdan önce eklemeyi deneyin:

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

C-h f declare-function Sana anlatır:

declare-functioniçindeki bir Lisp makrosu subr.el.

(declare-function FN FILE &optional ARGLIST FILEONLY)

Bayt-derleyiciye işlevinin FNtanımlandığını söyle FILE. FILEBağımsız değişken bayt derleyici tarafından kullanılır, ancak ile değil check-declaredosya için bir tanımını içerir olmadığını kontrol eder paketi FN.

FILEbir Lisp dosyası (bu durumda ".el" uzantı isteğe bağlıdır) veya bir C dosyası olabilir. C dosyaları Emacs "src/"dizinine göre genişletilir . Lisp dosyaları kullanılarak aranır locate-libraryve bu başarısız olursa, bildirimi içeren dosyanın konumuna göre genişletilir. Bir FILEbir ile "ext:"önek harici dosyasıdır. check-declarebulunursa bu tür dosyaları kontrol eder ve bulunmazsa hatasız atlar.

İsteğe bağlı 'argümanlarını ARGLISTbelirtir FNveya ' argümanlarını tbelirtmez FN. Atlanan ARGLISTvarsayılan olarak tdeğil nil: a nil ARGLISTboş bir bağımsız değişken listesi belirtir ve açık t ARGLIST, daha sonraki bir bağımsız değişken sağlamaya izin veren bir yer tutucudur.

Opsiyonel FILEONLYolmayan nilaraçlar check-declaresadece kontrol edecektir FILEtanımladığı değil, var FN. Bu, check-declaretanımayan fonksiyon tanımları için tasarlanmıştır , örn defstruct.

check-declareBu ifadenin amaçları doğrultusunda , bir satırdaki ilk boşluk olmayan alan olması gerektiğini unutmayın.

Daha fazla bilgi için bkz. Bilgi düğümü (elisp)Declaring Functions.


FILEONLYEldeki dava için sıfır olmayan bir tartışma gerekli midir? BTW, aynı cevabı verirdim ;-).
Tobias

@Tobias: FILEONLYBenim için burada gerekli görünmüyordu. Hangi olduğunu check-declaretanır fve gdefuns gösterir.
Drew

@ Çekti, bence son yorum hakkında emacs.stackexchange.com/q/39439 bağlamında fve gsadece mantıklı ?
phils

@phils: Evet, bunu söylemek istedim: FILEONLYbenim için burada gerekli görünmüyordu. Hangi defun check-declaretanıdığını gösterir gibi görünüyor increase-count. ;-)
Drew

3

Söz konusu tanımın içine yerleştirilmesinin yüzeysel olarak Stefan'ın doğru cevabı ile aynı sonucu elde eval-and-compileedeceğine inanıyorum :

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

Bununla birlikte, kullanım inceliklerini neredeyse eval-and-compilebilmiyorum ve dahası, bu yaklaşımın herhangi bir şekilde daha üstün olmasını beklemiyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.