Deklarasikan variabel dengan defvar
. Tidak ada cara lain untuk menghilangkan peringatan tersebut, dan ini benar-benar dianggap sebagai praktik yang baik.
Niat Anda untuk menjaga tabel simbol tetap rapi adalah hal yang baik, tetapi Anda tidak benar-benar melakukannya. Saya pikir Anda telah salah memahami semantik pengikatan variabel di Emacs Lisp, karena Anda tampaknya percaya bahwa dengan tidak mendeklarasikannya foo-state
akan dibatalkan ikatannya di buffer apa pun yang tidak menggunakan foo-mode
. Bukan itu masalahnya.
Dalam nama Emacs Lisp (alias simbol) bersifat global. Segera setelah foo-state
dievaluasi pertama kali, runtime membuat objek simbol baru untuk foo-state
dan memasukkannya ke dalam tabel simbol global (alias obarray
). Tidak ada tabel simbol lokal, jadi tidak masalah di mana foo-state
dievaluasi dan bagaimana caranya, foo-state
mengacu pada objek simbol yang sama di tempat mana saja (lihat Membuat Simbol).
Setiap objek simbol terdiri dari komponen (alias sel), salah satunya adalah sel variabel (lihat Komponen simbol). setq
memodifikasi pengikatan sistem saat ini, pada tingkat atas tanpa pengikatan leksikal ini secara efektif mengubah sel variabel dari objek simbol, sehingga nilai global dari variabel tersebut. Sekali lagi, tidak masalah di mana setq
dievaluasi. Sebenarnya jika beberapa bar-mode
dievaluasi (setq foo-state "bar")
, foo-state
akan terikat ke "bar" di foo-mode
juga, dan sebaliknya.
Jadi satu-satunya efek (defvar)
atas (setq)
adalah mendokumentasikan niat menggunakan simbol sebagai variabel global, jadi memberitahu orang lain untuk tidak mengubah variabel ini kecuali memang dimaksudkan untuk memanipulasi perilaku foo-mode
. Anda dapat melampirkan dokumentasi ke variabel, dan menandainya sebagai variabel yang didefinisikan dalam buffer Anda (C-h v foo-state
akan memberikan tautan untuk melompat ke definisi tersebut).
Karena Emacs Lisp tidak memiliki namespace dan – secara default – memiliki cakupan dinamis, dokumentasi pada dasarnya penting untuk menghindari konflik antar modul. Jika saya menulis bar-mode
menggunakan foo-mode
Anda, saya mungkin secara tidak sengaja mengikat ke foo-state
, memanggil foo-change-state
dan kemudian melihat mode saya berperilaku buruk karena suatu variabel tidak sengaja ditimpa. Mendeklarasikan foo-state
tidak membuat hal ini menjadi mustahil, tetapi setidaknya memungkinkan saya untuk menangkap kesalahan tersebut, karena C-h v foo-state
akan mengungkapkan bahwa variabel ini digunakan oleh mode lain, jadi sebaiknya saya tidak menggunakannya kecuali saya benar-benar bermaksud untuk memanipulasi mode itu.
Sebagai kata terakhir: Dalam semua teks "mode" yang disebutkan di atas dapat diganti dengan file Emacs Lisp. modes
tidak ada yang istimewa dalam hal simbol. Semua hal di atas juga berlaku untuk Emacs Lisp yang tidak mendeklarasikan mode, tetapi hanya berisi banyak fungsi.
person
lunaryorn
schedule
14.09.2012
C-h i g (elisp) Warning Tips RET
adalah tempat dokumentasi yang menjawab pertanyaan ini berada. - person phils   schedule 08.04.2014define-derived-mode
, seperti pada(define-derived-mode foo-mode nil "foo" "My nice major mode." (set (make-local-variable 'foo-state) "bar"))
. - person Stefan   schedule 16.04.2014Warning Tips
di Manual Emacs berisi kebohongan terang-terangan mengenaidefvar
: Definisi seperti itu tidak berpengaruh kecuali memberi tahu kompiler agar tidak memperingatkan tentang penggunaan variabel [...] dalam file ini.. Hal ini tentu saja dapat berdampak lebih besar daripada sekadar membungkam kompiler: [itu] juga mendeklarasikan variabel sebagai variabel khusus, sehingga selalu terikat secara dinamis meskipun 'pengikatan leksikal' adalah t. (kutipan diambil dari dokumentasi sebenarnya untukdefvar
). Mungkin saran diWarning Tips
ditulis sebelum pengenalan pengikatan leksikal di Emacs Lisp... - person ack   schedule 01.03.2018