एक बफर के लिए शाब्दिक-बंधन को सक्षम करने के संभावित नुकसान क्या हैं?


12

यह इस प्रश्न में लेक्सिकल-बाइंडिंग बनाम लेक्सिकल-लेट की चर्चा से प्रेरित था । जैसा कि लेक्सिकल-बाइंडिंग आपको उपयोगी क्लोजर रखने की क्षमता प्रदान करता है, जिसका उपयोग अन्य भाषाओं में जावास्क्रिप्ट की तरह किया जा सकता है, तो आप इसे हर समय सक्षम क्यों नहीं करेंगे?

पुराने Emacsen के साथ पीछे की संगतता मान लेना एक चिंता का विषय नहीं है कि यदि आप विरासत कोड बफ़र्स में इसे सक्षम कर रहे हैं तो आपको क्या नुकसान होने चाहिए?

जवाबों:


13

एक प्रमुख ख़तरा है कि के लिए बाध्यकारी अर्थ विज्ञान है अपरिभाषित चर-चर के साथ यानी परिभाषित नहीं defvarऔर दोस्तों के साथ-परिवर्तन lexical-bindingइसके बिना,: letबांध सब कुछ गतिशील है, लेकिन साथ lexical-bindingसक्षम अपरिभाषित चर बाध्य कर रहे हैं lexically , और यहां तक कि वर्तमान शाब्दिक दायरे में पूरी तरह से करता है, तो अप्रयुक्त elided ।

पुराना कोड कभी-कभी इस पर निर्भर करता है। वैकल्पिक सुविधाओं के लिए कठिन निर्भरता से बचने के लिए, यह संबंधित पुस्तकालय की आवश्यकता के बिना गतिशील चर को बांध देगा या स्वयं को चर घोषित करेगा:

(let ((cook-eggs-enabled t))
  (cook-my-meal))

यदि खाना पकाने की सुविधा वैकल्पिक है, तो हम उपयोगकर्ता पर अनावश्यक निर्भरता को लागू नहीं करना चाहते हैं, इसलिए हम उपयोग नहीं करते हैं (require 'cook)और इसके बजाय cook-my-mealफ़ंक्शन के ऑटोलॉडिंग पर भरोसा करते हैं ।

यह मानवीय पाठक के लिए स्पष्ट है जो cook-eggs-enabledस्थानीय चर नहीं है, लेकिन फिर भी cookयहां पुस्तकालय से कुछ वैश्विक गतिशील चर को संदर्भित करता है। lexical-bindingइस कोड के बिना इरादा के अनुसार काम करता है: cook-eggs-enabledगतिशील रूप से बाध्य है, चाहे परिभाषित किया गया हो या नहीं।

साथ lexical-bindingतथापि, यह टूट जाता है: cook-eggs-enabledअब बाध्य है lexically (और फिर अनुकूलित दूर है, क्योंकि यह उपयोग नहीं किया जाता), इसलिए वैश्विक गतिशील चर cook-eggs-enabledहै नहीं कभी सब पर छुआ है और अभी भी nilसमय से cook-my-mealकहा जाता है, तो हम आश्चर्यजनक रूप से किसी भी अंडे की ज़रूरत नहीं होगी हमारे भोजन में।

सौभाग्य से, ये मुद्दे बहुत आसान हैं : बाइट कंपाइलर स्वाभाविक रूप से यहां अप्रयुक्त लेक्सिकल बाइंडिंग के बारे में चेतावनी देता है।

यह फिक्स सरल है: या तो एक जोड़ें (require 'cook)(वैसे सुविधाओं के लिए जो वास्तव में वैकल्पिक नहीं हैं), या - कठिन निर्भरता से बचने के लिए - अपने स्वयं के कोड में चर को गतिशील चर के रूप में घोषित करें । इसके लिए एक विशेष defvarरूप है:

(defvar cook-eggs-enabled)

यह cook-eggs-enabledडायनामिक वैरिएबल के रूप में परिभाषित करता है , लेकिन डॉकस्ट्रिंग, load-history(और इस तरह find-variableऔर दोस्तों) या कुछ और को प्रभावित नहीं करता है, केवल वैरिएबल की बाध्यकारी प्रकृति को छोड़कर।


गतिशील मामले में, क्या कोड स्निपेट के खत्म cook-eggs-enabledहोने के बाद अनबाउंड होने का कारण नहीं होगा let? मुझे पूरा यकीन है कि मैं पहले भी इस तरह बग में भाग चुका हूं। डिफावर अंदर हो रहा था let, और letबाद में चर को अपनी प्रारंभिक (शून्य) स्थिति में बहाल कर दिया।
मालाबार

1
@ मालबाबा नहीं, वह एक अलग स्थिति है। कारण के लिए चर को परिभाषित करने का अंतिम पैराग्राफ देखें ।
चंद्रग्रहण
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.