एक प्रमुख ख़तरा है कि के लिए बाध्यकारी अर्थ विज्ञान है अपरिभाषित चर-चर के साथ यानी परिभाषित नहीं 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
बाद में चर को अपनी प्रारंभिक (शून्य) स्थिति में बहाल कर दिया।