`सेट-लोकल` क्या करता है, और मुझे इसका उपयोग कब करना चाहिए?


16

बफर-लोकल वैरिएबल की सभी विविधताओं पर मैं बिल्कुल स्पष्ट नहीं हूं, यहां तक ​​कि सभी डॉक और एसएक्स पर पोस्टिंग का एक गुच्छा पढ़ने के बाद भी।

यहाँ मेरी समझ का सारांश है:

(defvar foo ..)फ़ाइल के लिए एक गतिशील चर घोषित करता है। लेकिन चर (1) अन्य फ़ाइलों के लिए ज्ञात नहीं है जब तक कि वे एक defvar बयान के रूप में अच्छी तरह से शामिल नहीं करते हैं , और (2) चर दायरे में वैश्विक है, बफर स्थानीय नहीं।

(make-variable-buffer-local foo)defvarउपर्युक्त के बाद संकलक और बाकी सभी को बताता है कि चर फू को हर जगह बफर-लोकल के रूप में माना जाना है, जब यह सेट होता है। इसलिए यह स्टेटमेंट बफर-लोकल वैरिएबल घोषित करने, दोनों स्टेटमेंट्स को फाइल में बैक-टू-बैक डालने के लिए अच्छा स्टाइल है।

(defvar xxx ...)                    ;declare xxx with global scope
(make-variable-buffer-local 'xxx)   ;but now make it buffer-local everywhere

सुविधा के लिए, (defvar-local xxx ...)फॉर्म को ऊपर की दो लाइनों के स्थान पर एक लाइन के रूप में इस्तेमाल किया जा सकता है:

(defvar-local xxx ...)       ;make xxx buffer local everywhere

एक बार उपरोक्त के रूप में घोषित किया गया, चर xxx का उपयोग सेट स्टेटमेंट में किसी भी अन्य चर की तरह किया जा सकता है।

अगर मैं सिर्फ एक बफर-स्थानीय चर का एक उदाहरण चाहता हूं जो पहले से ही एक वैश्विक गतिशील चर है, तो मैं निम्नलिखित घोषणाओं का उपयोग करूंगा। पहले वाला वैश्विक-स्कोप डायनेमिक चर घोषित करता है, और दूसरा स्टेटमेंट वर्तमान बफ़र में उस वेरिएबल के बफर-लोकल वर्जन का सिर्फ एक उदाहरण बनाता है:

(defvar xxx ...)             ;declare xxx with global scope
(make-local-variable 'xxx)   ;make xxx local in this buffer only

अब मेरे खोज प्रश्नों के लिए (उपरोक्त सभी इस पर अंतर्निहित प्रश्न थे कि क्या मेरी समझ सही है)।

चरों का मान सेट करते समय, मैं उपयोग setqया कर सकता हूँ setq-local। कब setq-localइस्तेमाल किया जाना चाहिए? क्यों?

यदि मैं setq-localबफर-लोकल वर्जन, या नॉन-बफर-लोकल वर्जन पर उपयोग करता हूं तो क्या होगा ?

क्या घोषित चर के setq-localलिए आवश्यक है defvar-local?

क्या setq-localसामान्य defvarघोषित चर इसे बफर-स्थानीय चर में बदल देगा? (दूसरे शब्दों में, setq-localकिसी तरह एक (make-variable-local xxx)घोषणा के बराबर है ?


अतिरिक्त श्रम स्कॉट के लिए धन्यवाद। मैं यहां से अतिरिक्त बैकक्वॉट में डालूंगा।
केविन

2
(setq-local VAR VALUE)के लिए बस आशुलिपि है (set (make-local-variable VAR) VALUE), जो (और अभी भी) एक सामान्य मुहावरा था।
ड्रयू

जवाबों:


18

आपकी अधिकांश धारणाएँ करीब हैं। मैं कुछ समय बाद उल्लेख करूंगा। लेकिन, पहला मुख्य सवाल।

रूप setq-localकेवल एक सुविधा है, यह उसी प्रकार है जैसे कि make-local-variableबाद में करना setq। यदि आपने C-h f setq-localदस्तावेज़ को देखने के लिए किया था और उस स्रोत के माध्यम से क्लिक किया था जिसे आपने देखा होगा। इस तरह मैंने अपनी पहली धारणा को सत्यापित किया। कोड थोड़ा अस्पष्ट है, हालांकि, चूंकि यह इस तथ्य की तरह चीजों पर अनुकूलन कर रहा है जो make-local-variableवास्तव में चर को ही वापस करता है। उपयोग करना setq-localकुछ कोड में स्थानीयता को इंगित करने का एक तरीका है, ताकि दूसरों को पता चले कि कोड वैरिएबल के वैश्विक मूल्य के साथ नहीं खेल सकता है। आपको स्थानीय चर तक पहुंचने के लिए इसका उपयोग करने की आवश्यकता नहीं है। किसी भी चर को बफर-लोकल बनाया जा सकता है और यह चर को छूने वाले सभी कोड को प्रभावित करेगा (सिवाय इसके कि वह वैश्विक प्रतिलिपि प्राप्त करने के लिए अपने तरीके से बाहर जाता है setq-defaultया इसी तरह)।

यही प्राथमिक उत्तर है। अब, आपकी पृष्ठभूमि में कुछ चीजें हैं जो थोड़ी दूर हैं। चूंकि आपने इस बारे में पूछा था, इसलिए मैं कुछ चीजों को संबोधित करूंगा।

पहला "अन्य फ़ाइलों के लिए ज्ञात नहीं है"। यह वास्तव में सच नहीं है। कोई भी कोड किसी भी वैश्विक चर को संदर्भित कर सकता है (इसीलिए उन्हें "वैश्विक" कहा जाता है) defvar(और C-h f defvarऐसा कहता है) सहित । वास्तव में, प्रत्येक वैश्विक चर के लिए केवल एक मुख्य defvar(डॉकस्ट्रिंग और डिफ़ॉल्ट मूल्य के साथ) होना चाहिए । एक defvarबस चर नाम के साथ एक बाइट-संकलक चेतावनी को दबाने के लिए इस्तेमाल किया जा सकता। Emacs केवल पहले वाले से मान का उपयोग करता है और पिछले एक से डॉकस्ट्रिंग का। यदि defvarमान / डॉकस्ट्रिंग के साथ कई एस हैं तो वे कोड पढ़ने वाले लोगों को भ्रमित कर सकते हैं। और फ़ाइलें लोड करने का क्रम मायने रखेगा।

कुछ चर केवल बफर-स्थानीय के रूप में उपयोग किए जाने का इरादा रखते हैं और वे हैं जो उपयोग करते हैं defvar-local(या दो भाग defvar/ make-variable-buffer-localजिसके लिए यह छोटा है, ज्यादातर पुराने कोड में शॉर्ट फॉर्म को जोड़ा गया था)। इससे सभी बफर में बफर-लोकल हो जाता है। कुछ चर के लिए, उनका प्राथमिक उपयोग बफर-लोकल नहीं है, लेकिन किसी कारण से आप चाहते हैं कि एक बफर का अलग मूल्य हो। जब आप उपयोग करते हैं make-local-variable, तो आमतौर पर कुछ बफर सेटअप कोड में लगभग कभी भी सही नहीं होता है defvar

और एक सामान्य बात के defvarरूप में , रूपों के दो उद्देश्य हैं। एक के पास कुछ डॉक्यूमेंटेशन हैं, ताकि C-h vदूसरों को यह जानने के लिए इस्तेमाल किया जा सके कि चर क्या है। दूसरा "डिफ़ॉल्ट" मान घोषित करना है, ताकि चर हमेशा सेट हो। डिफ़ॉल्ट मान की घोषणा केवल एक वैरिएबल के वैश्विक (या डिफ़ॉल्ट) उदाहरण को प्रभावित करती है, और इसका उपयोग केवल तभी किया जाता है यदि वह उदाहरण पहले से ही किसी चीज़ के लिए सेट नहीं है। इसका मतलब यह है कि यदि आप setqकुछ परिवर्तनशील हैं और फिर defvar(उदाहरण के माध्यम से require) के साथ फाइल को शामिल करते हैं , तो डिफावर मान को नहीं बदलेगा।

If अधिक सटीक रूप से, defvarयदि यह पहले से ही सेट है (तो यह डॉकस्ट्रिंग सेट नहीं करता है), लेकिन वैरिएबल के मूल्य को संशोधित नहीं करता है; इसका मतलब यह है कि (setq some-variable)पैकेज के डिफ़ॉल्ट मान को ओवरराइड करने के लिए पैकेज लोड होने से पहले उपयोगकर्ता इनिट फ़ाइल कर सकता है ।


1
बहुत स्पष्ट उत्तर के लिए धन्यवाद, यह बहुत मदद करता है। जब मैंने "अन्य फ़ाइलों के लिए ज्ञात नहीं" वाक्यांश का उपयोग किया था तो मैं मुक्त चर चेतावनियों के बारे में सोच रहा था क्योंकि वे अन्य फाइलें सोचेंगी कि चर मुक्त है जब तक कि मैं उनके लिए एक डिफावर भी नहीं जोड़ता। मुझे आपका कथन पसंद आया जो set-localपाठकों को बताता है कि एक स्थानीय संस्करण सेट किया जा रहा है। कुछ भी मैं अपने कोड की पठनीयता में सुधार कर सकता हूं वह अच्छा है! पुनश्च। मैं स्रोत पर अधिक बार क्लिक करने का प्रयास करूंगा; मेरे विकास के वर्तमान स्तर पर, यह अक्सर शब्दार्थ में नहीं मिलता है ... :-)
केविन

1
"वहाँ केवल एक ही होना चाहिए defvarप्रत्येक वैश्विक चर के लिए" सख्ती से सही नहीं है - ऐसी परिस्थितियाँ होती हैं, जब (defvar VARNAME) बिना एक मूल्य घोषित किया जाना चाहिए, उचित परिभाषा (प्रारंभिक मूल्य और आदर्श रूप से docstring के साथ) की स्वतंत्र रूप से है कि VARNAME की।
फिल्स

2
ध्यान दें कि setq-localऔर defvar-localकेवल Emacs 24.3 में पेश किए गए थे।
फिल्स

1
@phils, क्या आप उन स्थितियों की पहचान कर सकते हैं, जिनके बारे में आप बात करते हैं, जहां बिना मूल्य के (defvar varname)घोषित किया जाना चाहिए ? मैं सोच रहा हूं कि ड्रू ने एक और सूत्र में सुझाव दिया था जब मैं पूछ रहा था कि ग्लोबल्स के लिए मेरी फाइलों में मुफ्त चर चेतावनियों से कैसे छुटकारा पाया जाए जो मैंने कहीं और घोषित किया था। मैं अब वह करता हूं। क्या वह स्थिति है जिससे आप बात करते हैं?
केविन

1
बाइट-संकलन चेतावनी से बचना एक कारण है, हाँ (देखें C-h i g (elisp) Warning Tips)। अन्य लेक्सिकल-बाइंडिंग का उपयोग करते हुए पुस्तकालयों के लिए है, यह सुनिश्चित करने के लिए (यदि आवश्यक हो) कि एक चर गतिशील रूप से बाध्य होने के बजाय बाध्य है।
फिल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.