2011-11-24 18 views
7

¿Cuál es la forma idiomática de implementar callbacks polimórficos en elisp?Devolución de llamada polimórfica en Emacs/Elisp

Específicamente, supongamos que tengo un modo menor con una función que realiza una determinada operación y luego invoca otra función. Esta segunda función debe tener una implementación diferente dependiendo de si el búfer actual contiene un archivo C++ o un archivo Java.

Alternativamente, supongamos que quiero sobrecargar variables en lugar de funciones. Por ejemplo, deseo invocar algún ejecutable externo, y uno de los argumentos que se le pasan difiere dependiendo de si el búfer actual tiene un archivo C++ o un archivo Java. Quiero ser capaz de construir la línea de comando en una función genérica y sustituir el argumento en función del contenido del búfer. ¿Es make-variable-buffer-local el enfoque correcto? ¿En qué punto (y por qué mecanismo) se supone inicialmente que se establecerán estas variables locales?

Respuesta

5

supongo tienes una variedad de enfoques. Algunas opciones, que vienen a la mente para su función de devolución de llamada son:

  1. las variables locales al búfer, como usted ha mencionado.

    Cómo se establece realmente dependerá de su caso de uso, pero puede implementar ganchos de modos principales específicos, o after-change-major-mode-hook para el caso general.

    make-variable-buffer-local es ciertamente el enfoque correcto si desea que la variable siempre sea buffer-local.

  2. Alist mapear modos principales a su función asociada.

    Configure esto para todos los modos que necesite y luego realice la búsqueda para el modo principal actual.

  3. Simplemente genere el nombre de la función basándose en el nombre del modo principal, llamándolo si existe dicha función.

En todos los casos, es probable que utilizaría funcall o apply para ejecutar la función seleccionada.

Los números 1 y 2 también serían relevantes para la segunda parte de su pregunta.

+1

Me he dado cuenta de que 'make-variable-buffer-local' y' funcall' es el enfoque adoptado con 'indent-line-function', entre otros. – Ray

1

Si está editando un archivo C++ o java, ese búfer debe estar en c++-mode o java-mode respectivamente. Por lo que podría hacer algo como lo siguiente:

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