2011-11-24 24 views
7

में पॉलिमॉर्फिक कॉलबैक elisp में polymorphic कॉलबैक को लागू करने के लिए बेवकूफ तरीका क्या है?Emacs/Elisp

विशेष रूप से, मान लें कि मेरे पास एक ऐसा फ़ंक्शन वाला मामूली मोड है जो एक निश्चित ऑपरेशन करता है और फिर किसी अन्य फ़ंक्शन को आमंत्रित करता है। इस दूसरे फ़ंक्शन में एक अलग कार्यान्वयन होना चाहिए, इस पर निर्भर करता है कि वर्तमान बफर में सी ++ फ़ाइल या जावा फ़ाइल है या नहीं।

वैकल्पिक रूप से, मान लीजिए कि मैं कार्यों के बजाय चर को अधिभारित करना चाहता हूं। उदाहरण के लिए, मैं कुछ बाहरी निष्पादन योग्य को आमंत्रित करना चाहता हूं, और इसके लिए पारित तर्कों में से एक इस बात पर निर्भर करता है कि वर्तमान बफर में सी ++ फ़ाइल या जावा फ़ाइल है या नहीं। मैं एक सामान्य कार्य में कमांड लाइन बनाने में सक्षम होना चाहता हूं और बफर की सामग्री के आधार पर एक तर्क को प्रतिस्थापित करना चाहता हूं। make-variable-buffer-local सही दृष्टिकोण है? किस बिंदु पर (और किस तंत्र द्वारा) इन स्थानीय चरों को शुरू में सेट किया जाना चाहिए?

उत्तर

5

मुझे लगता है कि आपके पास विभिन्न दृष्टिकोण हैं। आपके कॉलबैक फ़ंक्शन के लिए कुछ विकल्प जो ध्यान में रखते हैं वे हैं:

  1. बफर-स्थानीय चर, जैसा आपने बताया है।

    आप इसे कैसे सेट करते हैं, यह वास्तव में आपके उपयोग के मामले पर निर्भर करेगा, लेकिन आप सामान्य मामले के लिए विशिष्ट प्रमुख मोड हुक, या after-change-major-mode-hook लागू कर सकते हैं।

    make-variable-buffer-local निश्चित रूप से सही दृष्टिकोण है यदि आप चर को हमेशा बफर-स्थानीय होने की इच्छा रखते हैं।

  2. एक सहयोगी उनके संबंधित फ़ंक्शन में प्रमुख मोड मैपिंग।

    यह आवश्यक सभी मोड के लिए इसे कॉन्फ़िगर करें, और फिर वर्तमान प्रमुख मोड के लिए लुक-अप करें।

  3. बस बड़े मोड नाम के आधार पर फ़ंक्शन नाम उत्पन्न करें, अगर ऐसा फ़ंक्शन मौजूद है तो इसे कॉल करें।

सभी मामलों में, संभावना है कि आप चयनित समारोह को चलाने के लिए funcall या apply का प्रयोग करेंगे रहे हैं।

संख्या 1 और 2 आपके प्रश्न के दूसरे भाग के लिए प्रासंगिक भी होंगे।

+1

मैंने देखा है कि 'मेक-वेरिएबल-बफर-लोकल' और 'funcall'' इंडेंट-लाइन-फ़ंक्शन 'के साथ लिया गया दृष्टिकोण है, दूसरों के बीच। – Ray

1

यदि आप सी ++ या जावा फ़ाइल संपादित कर रहे हैं, तो बफर c++-mode या java-mode क्रमशः होना चाहिए। तो आप निम्नलिखित की तरह कुछ कर सकता है:

(defun function1() 
    (interactive) 
    ;; put your generic code here 
    (cond ((string= major-mode "c++-mode") 
    (function2-cpp)) 
    ((string= major-mode "java-mode") 
    (function2-java)) 
    (t (message "I don't know what mode this is")))) 

(defun function2-cpp() 
    (message "this is cpp mode")) 

(defun function2-java() 
    (message "this is java mode"))