मैं nadvice का उपयोग कैसे करूँ?


29

मेरा कॉन्फ़िगरेशन सलाह से भरा है, और मैं नए चमकदार न्यूनतम nadvice.elपैकेज के बारे में सुनता रहता हूं ।

मैंने मैनुअल की खोज की है, और मैंने स्रोत को पढ़ा है , लेकिन मैं खुले तौर पर स्वीकार करूंगा: मुझे अभी भी पता नहीं है कि वास्तव में इसका उपयोग कैसे करें।

क्या कोई भी मुझे एक गाइड की ओर इशारा कर सकता है, या मुझे बता सकता है कि अपनी पुरानी शैली की सलाह को कैसे पोर्ट करना शुरू करें?


7
प्रश्न के लिए +1। यदि आपने नियमावली खोज ली है और आपको जो चाहिए वह नहीं मिला है, तो कृपया (डॉक) बग रिपोर्ट दाखिल करने पर विचार करें M-x report-emacs-bug:। कुछ डेवलपर्स कभी-कभी दस्तावेजीकरण से अधिक विकसित करना पसंद करते हैं। ;-) यह महत्वपूर्ण है कि Emacs स्वयं दस्तावेज़।
ड्रयू

2
मैनुअल वास्तव में उस पर एक खंड है, देखें (जानकारी "(elisp) पोर्टिंग पुरानी सलाह") । यह विस्तृत सूचकांक में सूचीबद्ध नहीं है, हालांकि जो भी कारण हो।
थामासा


3
का उपयोग कर कुछ उदाहरण nadviceमेरी config से: : के बाद , : फिल्टर-रिटर्न , : चारों ओर , : से पहले-जब तक
कौशल मोदी

1
@wasamasa मुझे डर है कि यह खंड पूरी तरह से दूर है। मेरे पास कुछ सलाह हैं (शायद सिर्फ एक, हम देखेंगे) जो अधिक जटिल हैं। क्या मुझे यहां प्रत्येक के लिए एक प्रश्न बनाना चाहिए?
PythonNut

जवाबों:


22

आपके लिए आवश्यक सभी जानकारी शामिल है 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, सिवाय इसके कि यह (जैसे लिखने की त्रुटियों के कारण) मदद बाइट संकलक समारोह के नाम के रूप में पहचान प्रतीकों और इस तरह लापता कार्यों की पहचान।


स्टीफन मोननियर के साथ हुई चर्चा के अनुसार , हैश-कोट्स का उपयोग यहाँ सभी तर्कों में नहीं किया जाना चाहिए .. यह (advice-add 'find-file :around #'my-find-file-advice-print-arguments)और इसी तरह होना चाहिए (advice-remove 'find-file #'my-find-file-advice-print-arguments)
कौशल मोदी मोदी

मुझे लगता advice-addहै कि सीमा मामला है। व्यक्तिगत रूप से मैं ' ↔ #'फंक्शन के नामों में टाइपोस की पहचान करने में मदद के रूप में भेद पर विचार करता हूं , इसलिए यहां यह संभवत: इस बात पर निर्भर करेगा कि किसी ने फ़ंक्शन को सलाह के समय परिभाषित करने की अपेक्षा की है या नहीं।
kdb

@kdb मैं अंततः अपने लिए यह पता चला (के बाद मैं के लिए डॉक्स में भाग गया add-function)। मुझे लगता है कि डॉक्स ने यह स्पष्ट कर दिया है। मैं इसके लिए एक पैच बनाने के लिए देख सकता हूँ।
PythonNut

@kdb क्या आपका मतलब है "यह दिखाता है C-h f find-file, नहीं C-x?
Peeja

@Peeja हाँ, इसे सही किया।
kdb
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.