के साथ संगतता Emacs 24 स्थानीय चर के लिए वैकल्पिक शब्दावली बाइंडिंग जोड़ा। XEmacs और पिछले Emacs संस्करणों के साथ संगतता बनाए रखते हुए, मैं अपने मॉड्यूल में इस कार्यक्षमता का उपयोग करना चाहता हूं।Emacs में लेक्सिकल स्कोप: पुराने Emacsen
Emacs 24 से पहले, lexical-let
cl-macs
में परिभाषित फॉर्म का उपयोग करके बंद करने का सबसे आसान तरीका था, जो कुछ चालाक मैक्रो चालबाजी के साथ अक्षीय दायरे को अनुकरण करता था। हालांकि इस elisp प्रोग्रामर के बीच बेहद लोकप्रिय कभी नहीं था, यह काम किया है, वास्तविक और कुशल बंद बनाने, जब तक कि आप इस स्यूडोकोड में के रूप में उन्हें lexical-let
में रैप करने के लिए याद किया,:
(defun foo-open-tag (tag data)
"Maybe open TAG and return a function that closes it."
... do the work here, initializing state ...
;; return a closure that explicitly captures internal state
(lexical-let ((var1 var1) (var2 var2) ...)
(lambda()
... use the captured vars without exposing them to the caller ...
)))
सवाल यह है: क्या है Emacs 23 और XEmacs के लिए समर्थन बनाए रखते हुए, नई शब्दावली बाइंडिंग का उपयोग करने का सबसे अच्छा तरीका है? वर्तमान में मैं यह एक पैकेज विशेष मैक्रो फैलता को परिभाषित द्वारा हल lexical-let
में या साधारण let
कि क्या lexical-binding
बाध्य और सच है पर निर्भर करता है में:
(defmacro foo-lexlet (&rest letforms)
(if (and (boundp 'lexical-binding)
lexical-binding)
`(let ,@letforms)
`(lexical-let ,@letforms)))
(put 'foo-lexlet 'lisp-indent-function 1)
... at the end of file, turn on lexical binding if available:
;; Local Variables:
;; lexical-binding: t
;; End:
यह समाधान काम करता है, लेकिन यह भद्दा लगता है, क्योंकि नए विशेष रूप से गैर है मानक, ठीक से हाइलाइट नहीं करता है, edebug
के तहत कदम नहीं उठाया जा सकता है, और आम तौर पर खुद पर ध्यान खींचता है। क्या कोई बेहतर तरीका है?
होशियार (जरूरी अच्छा नहीं) समाधान है कि कोड को बंद बनाने के लिए मानक रूपों का उपयोग कर जारी रखने की अनुमति के लिए संपादित करें विचारों का
दो उदाहरण:
एक सलाह का प्रयोग करें या
lexical-let
के तहतlexical-let
के तहतlexical-let
को केवल उन प्रतीकों को असाइन किया गया है जो किसी भी तरह से लंबवत रूप से स्कॉप्ड किए गए हैं। यह सलाह केवलfoo.el
के बाइट-संकलन के दौरान अस्थायी रूप से सक्रिय की जाएगी, ताकिlexical-let
का अर्थ शेष Emacs के लिए अपरिवर्तित बनी रहे।पुराने Emacsen के तहत
lexical-let
पर गैर-प्रीफ़िक्स्ड प्रतीकों केlet
संकलित करने के लिए एक मैक्रो/कोड-वॉकर सुविधा का उपयोग करें। यह फिर से केवलfoo.el
के बाइट-संकलन के दौरान लागू होगा।
चिंतित मत हो, तो इन विचारों overengineering की गंध: मैं के रूप में है उन्हें इस्तेमाल करने का प्रस्ताव नहीं कर रहा हूँ। मुझे उपरोक्त मैक्रो के विकल्पों में दिलचस्पी है जहां पैकेज को लोडिंग/संकलन की कुछ अतिरिक्त जटिलताओं की कीमत के बंद होने के लिए निकर्स पोर्टेबल उपयोग का लाभ मिलता है।
संपादित 2
के रूप में कोई भी एक समाधान है कि मॉड्यूल उन्हें Emacs के आराम के लिए तोड़ने के बिना let
या lexical-let
का उपयोग कर रखने के लिए, मैं स्टीफन के जवाब को स्वीकार कर रहा हूँ की अनुमति होगी के साथ कदम रखा है, जो बताता है कि उपरोक्त मैक्रो ऐसा करने का तरीका है। इसके अलावा, उत्तर bound-and-true-p
का उपयोग करके और एडबग और लिस्प-इंडेंट के लिए एक सुंदर घोषणा जोड़कर मेरे कोड पर सुधार करता है।
अगर किसी के पास इस संगतता परत के लिए वैकल्पिक प्रस्ताव है, या उपर्युक्त विचारों का एक सुंदर कार्यान्वयन है, तो मैं उन्हें उत्तर देने के लिए प्रोत्साहित करता हूं।
यदि मैं सामान्य लिस्प में इस मैक्रो रैपर को लिख रहा था, तो शायद मैं यहां एक ही मूल दृष्टिकोण का उपयोग करूंगा। सिवाय इसके कि मैं शीर्ष स्तर पर एक एकल डिफैमक्रो ब्लै-लेक्सलेट रखकर, नील 'eval, और उसके बाद एक संकलन समय है अगर यह निर्धारित करता है कि कोड का विस्तार करने के लिए कौन सा रूप है (चलो या लेक्सिकल- इस मामले में चलो)। मैं इसे उत्तर के रूप में नहीं डाल रहा हूं b/c यह एक सामान्य लिस्पे दृष्टिकोण है, और आपके द्वारा उपयोग किए जाने वाले वही मूल दृष्टिकोण है। –
अच्छा बिंदु, मैंने अब 'if' macroexpansion-time को स्थानांतरित करने के लिए उदाहरण को संशोधित किया है। हालांकि, प्रश्न में बताए गए 'फू-लेक्सलेट' के खिलाफ तर्क अभी भी खड़े हैं। – user4815162342