2011-11-24 12 views
7

elispで多態的なコールバックを実装する慣用方法は何ですか?Emacs/Elispにおける多態的コールバック

具体的には、特定の操作を実行して別の関数を呼び出す関数を持つマイナーモードがあるとします。この2番目の関数は、現在のバッファにC++ファイルまたはJavaファイルが含まれているかどうかによって異なる実装を持つ必要があります。

また、関数ではなく変数をオーバーロードしたいとします。たとえば、いくつかの外部実行可能ファイルを呼び出すとします。渡される引数の1つは、現在のバッファにC++ファイルまたはJavaファイルがあるかどうかによって異なります。私はジェネリック関数でコマンドラインを構築し、バッファの内容に応じて1つの引数を代入できるようにしたい。 make-variable-buffer-localは正しいアプローチですか?これらのローカル変数は、どの時点(どの機構によって)に最初に設定されていたのでしょうか?

答えて

5

私は推測しますあなたにはさまざまなアプローチがあります。あなたのコールバック関数のために覚えておくべきいくつかのオプションは以下の通りです:

  1. 上記のようなバッファローカル変数。

    どのように設定するかは、実際の使用例に依存しますが、特定のメジャーモードフックを実装するか、一般的なケースでafter-change-major-mode-hookを実装することがあります。

    make-variable-buffer-local変数を常にバッファローカルにしたい場合は、確かに正しい方法です。

  2. メリットはメジャーモードを関連する機能にマッピングします。

    必要なすべてのモードにこの設定を行い、現在のメジャーモードのルックアップを実行します。

  3. メジャーモード名に基づいて関数名を生成し、そのような関数が存在する場合はそれを呼び出すだけです。すべての場合において

、チャンスはあなたが選択した機能を実行するためにfuncallまたはapplyを使用することになります。

数字1と2は、質問の第2部分と関連があります。

+1

私は 'make-variable-buffer-local'と' funcall'が 'indent-line-function'で取り上げられたアプローチであることに気付きました。 – Ray

1

C++またはjavaファイルを編集する場合、そのバッファはそれぞれ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")) 
関連する問題