आपके लिए आवश्यक सभी जानकारी शामिल है C-h f add-functionजिसमें अंतर्निहित तंत्र का वर्णन है advice-add।
नई सलाह प्रणाली मूल रूप से तालिका में वर्णित फ़ंक्शन द्वारा किसी फ़ंक्शन की वर्तमान परिभाषा को प्रतिस्थापित करने की तरह काम करती है, जो
C-h f add-functionआपकी पसंद की पसंद के आधार पर WHERE
, केवल ट्रैकिंग के लिए क्लीनर क्या स्रोत फ़ाइल में परिभाषित किया गया है।
:aroundविकल्प के साथ एक उदाहरण
सबसे सामान्य मामला :aroundविकल्प है, इसलिए मैं उसके लिए एक उदाहरण देता हूं। ( WHEREसंभव होने पर समर्पित मापदंडों का उपयोग करना बेहतर है, लेकिन आप हर दूसरे को एक समान :aroundफ़ंक्शन द्वारा बदल सकते हैं
)।
एक उदाहरण के रूप में, आपको यह बताने की अनुमति देता है कि आप इसके उपयोग के बारे में कुछ डिबग find-file
करना चाहते हैं और printहर बार इसकी तर्क सूची को चाहते हैं । आप लिख सकते हैं
(defun my-find-file-advice-print-arguments (old-function &rest arguments)
"Print the argument list every time the advised function is called."
(print arguments)
(apply old-function arguments))
(advice-add #'find-file :around #'my-find-file-advice-print-arguments)
इस नए कार्यान्वयन के साथ, सलाह की जरूरत की हर चीज को तर्क के रूप में पारित किया जाता है। ad-get-argsअनावश्यक हो जाता है, क्योंकि तर्कों को सामान्य कार्य तर्कों के रूप में सलाह कार्य के लिए पारित किया जाता है (
WHEREतर्कों के लिए जिसके लिए यह समझ में आता है)। सलाह ad-do-itअनावश्यक :aroundहो जाती है क्योंकि फ़ंक्शन और तर्कों को सलाह मिलती है, इसलिए (ad-do-it)फॉर्म को बदल दिया जाता है
(apply old-function arguments)
या जब आपने तर्कों का नाम दिया है
(funcall old-function first-arg second-arg)
जो क्लीनर है क्योंकि इसमें कोई जादू के रूप शामिल नहीं हैं। तर्कों को संशोधित करना बस संशोधित मूल्यों को पारित करने से होता है OLD-FUNCTION।
अन्य WHEREमूल्य
डॉक्सस्ट्रिंग में add-functionसभी सलाह स्थानों (या "कॉम्बीनेटर") की एक तालिका शामिल है, और वे किसके समकक्ष हैं, और सलाहित कार्य के lambdaबराबर व्यवहार के संदर्भ में कार्यक्षमता की व्याख्या करते हैं :
`:before' (lambda (&rest r) (apply FUNCTION r) (apply OLDFUN r))
`:after' (lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
`:around' (lambda (&rest r) (apply FUNCTION OLDFUN r))
`:override' (lambda (&rest r) (apply FUNCTION r))
`:before-while' (lambda (&rest r) (and (apply FUNCTION r) (apply OLDFUN r)))
`:before-until' (lambda (&rest r) (or (apply FUNCTION r) (apply OLDFUN r)))
`:after-while' (lambda (&rest r) (and (apply OLDFUN r) (apply FUNCTION r)))
`:after-until' (lambda (&rest r) (or (apply OLDFUN r) (apply FUNCTION r)))
`:filter-args' (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
`:filter-return'(lambda (&rest r) (funcall FUNCTION (apply OLDFUN r)))
(cited from `C-h f add-function')
जहां FUNCTION सलाह फ़ंक्शन है और OLDFUN फ़ंक्शन जहां सलाह जोड़ी जाती है। एक बार में उन सभी को समझने की कोशिश मत करो, बस एक WHEREप्रतीक का चयन करें जो फिटिंग लगता है और उस एक को समझने की कोशिश करें।
या सिर्फ उपयोग करें :around। जहाँ तक मैं सब कुछ के लिए विशेष WHEREएस का उपयोग करने का एकमात्र लाभ बता सकता हूं :aroundकि आपको C-h f ADVISED-FUNCTION
सलाह के डॉकस्ट्रिंग को पढ़ने से पहले देखने से थोड़ा अधिक जानकारी मिलती है । जब तक आप उस सलाह को प्रकाशित करने वाले कोड को प्रकाशित करने की योजना नहीं बनाते हैं जो शायद मायने नहीं रखता है।
नामित सलाह कार्य
मैं सलाह के रूप में नामित कार्यों का उपयोग करने की सलाह देता हूं क्योंकि यह कई फायदे प्रदान करता है (उनमें से कुछ हुक के लिए नामित कार्यों का उपयोग करने के लिए भी लागू होते हैं):
यह के C-h f find-fileरूप में दिखाता है
:around advice: `my-find-file-advice-print-arguments'
सलाह फ़ंक्शन की परिभाषा से लिंक करना, जिसमें हमेशा की तरह उस फ़ाइल का लिंक होता है जहां इसे परिभाषित किया गया था। यदि सलाह को एक lambdaफॉर्म के रूप में सीधे परिभाषित किया गया था, advice-add
तो डॉकस्ट्रिंग को इनलाइन (लंबे समय के लिए गड़बड़ी?) दिखाया जाएगा और कुछ भी नहीं इंगित करेगा कि इसे कहां परिभाषित किया गया है।
आप के साथ सलाह निकाल सकते हैं
(advice-remove #'find-file #'my-find-file-advice-print-arguments)
आप advice-addपुराने संस्करण को सक्रिय रखने के लिए पुनरावर्ती या जोखिम के बिना सलाह की परिभाषा को अपडेट कर सकते हैं
(जैसे advice-addकि किसी बदलाव के साथ चलने
lambdaको नई सलाह के रूप में पहचाना जाएगा, पुराने को अपडेट के रूप में नहीं)।
साइड टिप्पणी#'function अंकन मूल रूप से करने के लिए बराबर है
'function, सिवाय इसके कि यह (जैसे लिखने की त्रुटियों के कारण) मदद बाइट संकलक समारोह के नाम के रूप में पहचान प्रतीकों और इस तरह लापता कार्यों की पहचान।
M-x report-emacs-bug:। कुछ डेवलपर्स कभी-कभी दस्तावेजीकरण से अधिक विकसित करना पसंद करते हैं। ;-) यह महत्वपूर्ण है कि Emacs स्वयं दस्तावेज़।