emacs "मुक्त चर के संदर्भ" बाइट-संकलन चेतावनी से छुटकारा पाएं




elisp (2)

मैं एक एमएसीएस प्रमुख मोड लिख रहा हूं, जो कुछ राज्य को संग्रहीत करने के लिए बफर-स्थानीय चर का उपयोग करता है:

(defun foo-mode ()
  "My nice major mode"
  (interactive)
  (kill-all-local-variables)
  (setq mode-name "foo")
  (setq major-mode 'foo-mode)
  (set (make-local-variable 'foo-state) "bar"))

(defun foo-change-state ()
  (setq foo-state "baz"))

यह बहुत अच्छी तरह से काम करता है और संपत्ति है कि मेरे प्रमुख मोड का उपयोग नहीं कर किसी भी बफर में, foo-state चर बाध्य नहीं है (जो मेरी राय में एक अच्छी बात है, क्योंकि यह प्रतीकों तालिका को अव्यवस्थित करने से बचता है)।

हालाँकि, इस तरह के कोड का बाइट संकलित करना निम्नलिखित चेतावनी उत्पन्न करता है:

Warning: assignment to free variable `foo-state'

defvar का उपयोग करने से चेतावनी से छुटकारा defvar जाता है, लेकिन इसका दुष्प्रभाव यह है कि foo-state अब हर जगह बाध्य है, जो मेरी राय में अवांछनीय है।

क्या हर बफ़र में मोड-विशिष्ट चर को बाध्यकारी नहीं करते हुए भी चेतावनी से छुटकारा पाने का एक तरीका है? या क्या मैं गलत हूं जब मुझे लगता है कि इन चरों को विश्व स्तर पर घोषित नहीं किया जाना चाहिए?


चर को defvar साथ घोषित करें। चेतावनी को हटाने का कोई अन्य तरीका नहीं है, और यह वास्तव में अच्छा अभ्यास माना जाता है।

प्रतीक तालिका को अप्रयुक्त रखने का आपका उद्देश्य योग्य है, लेकिन आप वास्तव में ऐसा नहीं कर रहे हैं। मुझे लगता है कि आपने Emacs Lisp में वैरिएबल बाइंडिंग के शब्दार्थ को गलत समझा है, क्योंकि आपको लगता है कि इसे घोषित नहीं करने से foo-state किसी भी बफ़र में foo-mode का उपयोग नहीं करने से अनबाउंड होगा। ऐसी बात नहीं है

Emacs में लिस्प नाम (उर्फ प्रतीक) वैश्विक हैं । जैसे ही foo-state का पहली बार मूल्यांकन किया जाता है, रनटाइम foo-state लिए एक नया प्रतीक ऑब्जेक्ट बनाता है और इसे वैश्विक प्रतीक तालिका (उर्फ obarray ) में obarray । कोई स्थानीय प्रतीक तालिकाओं नहीं हैं, इसलिए यह कोई फर्क नहीं पड़ता कि foo-state का मूल्यांकन कहां और कैसे किया जाता है, foo-state किसी भी स्थान पर एक ही प्रतीक वस्तु को संदर्भित करता है ( प्रतीक बनाना ) देखें।

प्रत्येक प्रतीक वस्तु में घटक (उर्फ कोशिकाएं) होते हैं, जिनमें से एक चर कोशिका है ( प्रतीक घटकों को देखें)। setq सिस्टम के वर्तमान बंधन को संशोधित करता है, लेक्सिकल बाइंडिंग के बिना शीर्ष-स्तर पर यह प्रभावी ढंग से प्रतीक वस्तु के चर सेल को बदलता है, इस प्रकार चर का वैश्विक मूल्य। फिर, इससे कोई फर्क नहीं पड़ता कि setq का मूल्यांकन कहां किया जाता है। वास्तव में अगर कुछ bar-mode मूल्यांकन किया गया (setq foo-state "bar") , foo-state foo-mode भी "बार" के लिए बाध्य होगा और इसके विपरीत।

इस प्रकार (defvar) का एकमात्र प्रभाव (defvar) यह है कि प्रतीक को वैश्विक चर के रूप में उपयोग करने का इरादा रखता है, इसलिए दूसरों को इस चर को संशोधित नहीं करने के लिए कहना जब तक कि foo-mode के व्यवहार का हेरफेर न हो। आप चर को प्रलेखन संलग्न कर सकते हैं, और अपने बफर में परिभाषित के रूप में चिह्नित कर सकते हैं ( Ch v foo-state परिभाषा में कूदने के लिए एक लिंक प्रदान करेगा)।

चूंकि Emacs Lisp में नेमस्पेस की कमी है और यह डिफ़ॉल्ट रूप से - डायनैमिक रूप से स्कूप्ड है, इसलिए मॉड्यूल के बीच टकराव से बचने के लिए प्रलेखन मौलिक रूप से महत्वपूर्ण है। यदि मैंने आपके foo-mode bar-mode का उपयोग करते हुए एक bar-mode लिखा है, तो मैं गलती से foo-state लिए बाध्य हो सकता हूं, foo-change-state कॉल कर सकता हूं और फिर मेरे मोड को दुर्व्यवहार कर देख सकता हूं क्योंकि एक चर अनायास ही ओवरराइट हो गया था। foo-state घोषणा करना यह असंभव नहीं बनाता है, लेकिन यह कम से कम मुझे त्रुटि को पकड़ने की अनुमति देता है, क्योंकि Ch v foo-state यह प्रकट करेगा कि यह चर किसी अन्य मोड द्वारा उपयोग किया जाता है, इसलिए मैं बेहतर उपयोग नहीं करूंगा जब तक कि मैं वास्तव में इसका उपयोग न करूं उस मोड में हेरफेर करने का इरादा है।

अंतिम शब्द के रूप में: उपरोक्त सभी पाठ "मोड" में एमएसीएस लिस्प फाइलों के साथ प्रतिस्थापित किया जा सकता है। प्रतीकों के संबंध में modes कुछ खास नहीं हैं। उपरोक्त सभी भी Emacs लिस्प के लिए हैं जो मोड घोषित नहीं करते हैं, लेकिन बस फ़ंक्शन का एक गुच्छा होते हैं।


आप जो चाहते हैं वह करने का आधिकारिक तरीका (defvar foo-state) । एक दूसरे तर्क की अनुपस्थिति पर ध्यान दें। ध्यान दें कि इस तरह की घोषणा केवल उस फ़ाइल पर लागू होती है जहां यह पाया जाता है (या उस दायरे में जहां इसे पाया जाता है, अगर यह किसी फ़ंक्शन के अंदर उपयोग किया जाता है)।





elisp