2011-11-24 8 views
7

Qual è il modo idiomatico per implementare callback polimorfici in elisp?Richiamate polimorfiche in Emacs/Elisp

In particolare, supponiamo di avere una modalità secondaria con una funzione che esegue una determinata operazione e quindi richiama un'altra funzione. Questa seconda funzione dovrebbe avere un'implementazione diversa a seconda che il buffer corrente contenga un file C++ o un file Java.

In alternativa, supponiamo di voler sovraccaricare le variabili anziché le funzioni. Ad esempio, desidero richiamare un eseguibile esterno e uno degli argomenti passati è diverso a seconda che il buffer corrente abbia un file C++ o un file Java. Voglio essere in grado di costruire la riga di comando in una funzione generica e sostituire l'argomento a seconda del contenuto del buffer. make-variable-buffer-local l'approccio giusto? A che punto (e con quale meccanismo) queste variabili locali dovrebbero essere inizialmente impostate?

risposta

5

immagino hai una varietà di approcci. Alcune opzioni che ti vengono in mente per la tua funzione di callback sono:

  1. Variabili locali buffer, come hai menzionato.

    Il modo in cui impostarlo dipende in realtà dal caso di utilizzo, ma è possibile implementare specifici hook di modalità principale o after-change-major-mode-hook per il caso generale.

    make-variable-buffer-local è sicuramente l'approccio giusto se si desidera che la variabile sia sempre buffer-local.

  2. Un elenco che associa le principali modalità alla funzione associata.

    Configurare questo per tutte le modalità necessarie e quindi eseguire la ricerca della modalità principale corrente.

  3. È sufficiente generare il nome della funzione in base al nome della modalità principale, chiamandolo se esiste una funzione di questo tipo.

In tutti i casi, è probabile che si usa funcall o apply per eseguire la funzione selezionata.

I numeri 1 e 2 sono rilevanti anche per la seconda parte della domanda.

+1

Ho notato che 'make-variable-buffer-local' e' funcall' è l'approccio adottato con 'indent-line-function', tra gli altri. – Ray

1

Se si modifica un file C++ o java, il buffer deve essere in c++-mode o java-mode rispettivamente. Così si potrebbe fare qualcosa di simile alla seguente:

(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"))