次: , 前: Buffer-Local Variables, 上: Buffer-Local Variables


10.10.1 バッファローカルな変数の紹介

バッファローカルな変数には、特定のバッファに関連したバッファローカルな 束縛があります。 この束縛は、そのバッファがカレントバッファであるときに有効になります。 さもなければなんの効果もありません。 バッファローカルな束縛が有効なときに変数に設定すると、 新しい値はその束縛に入り、他の束縛は変更されません。 つまり、その変更は、変更を行ったバッファだけで見ることができるのです。

変数の通常の束縛、つまり、特定のバッファに関連していない束縛を デフォルトの束縛(default binding)と呼びます。 多くの場合、これはグローバル束縛です。

変数は、あるバッファ群ではバッファローカルな束縛を持ち、 他のバッファではそのような束縛を持たないようにできます。 変数に対する独自の束縛を持たないバッファすべてでは、 デフォルトの束縛を共有します。 (これには、新たに作成されるバッファも含む。) バッファローカルな束縛を持たないバッファで変数に設定すると、 (状況を複雑にするフレームローカルな束縛はないと仮定して) デフォルトの束縛を使います。 したがって、新たな値はデフォルトの束縛を見るバッファすべてで見えます。

バッファローカルな束縛のもっとも一般的な使い方は、 メジャーモードでコマンドのふるまいを制御する変数に変更することです。 たとえば、CモードやLispモードでは、変数paragraph-startを設定して、 空行だけが段落を区切るように指定します。 これには、CモードやLispモードになったバッファでは、 変数をバッファローカルにしてから、 そのモード用の新たな値を変数に設定するのです。 See Major Modes

バッファローカルな束縛を作る普通の方法は、 make-local-variableです。 メジャーモードのコマンドは典型的にこれを使います。 これはカレントバッファだけに影響します。 (これから作成するものも含めて)他のすべてのバッファは、 それ専用のバッファローカルな束縛を明示的に与えない限り、 デフォルト値を共有し続けます。

より強力な操作は、make-variable-buffer-localを呼び出して 変数を自動的にバッファローカルにするように印を付けることです。 これは、これから作成するものも含めたバッファすべてで、 変数をバッファローカルにすると考えることができます。 より正確には、変数がカレントバッファにローカルでなければ、 自動的に変数をカレントバッファにローカルにするように設定する効果があります。 すべてのバッファは通常どおり変数のデフォルト値を共有して始まりますが、 変数に設定するとカレントバッファにバッファローカルな束縛を作ります。 新たな値はバッファローカルな束縛に格納され、デフォルトの束縛は変更しません。 つまり、どのバッファでもデフォルト値をsetqでは変更できません。 デフォルト値を変更する唯一の方法は、setq-defaultを使うことです。

警告: 複数のバッファにおいて変数にバッファローカルな値があるときに、 変数をletで束縛してから、 別の束縛が有効である別のバッファに切り替えてletを抜けると、 Emacsをとても混乱させることになる。 こうすると、バッファローカルな束縛とデフォルトの束縛を混ぜ合わせてしまう。

混乱を避けるために、このような変数の使い方は避けてください。 別のバッファに切り替える各コード部分をsave-excursionで囲めば、 このような問題はありません。

     (setq foo 'b)
     (set-buffer "a")
     (make-local-variable 'foo)
     (setq foo 'a)
     (let ((foo 'temp))
       (set-buffer "b")
       body...)
     
     
     foo => 'a      ; バッファ`a'の古いバッファローカルな値が
                    ;   現在のデフォルト値
     (set-buffer "a")
     
     
     foo => 'temp   ; 消えているべきローカルなletの値が
                    ;   バッファ`a'の現在のバッファローカルな値

しかし、つぎに示すようにsave-excursionを使えば、この問題を回避できます。

     (let ((foo 'temp))
       (save-excursion
         (set-buffer "b")
         body...))

body内でのfooへの参照は、 バッファ`b'のバッファローカルな束縛を使います。

ファイルでローカル変数の値を指定していると、 そのファイルを訪問したときに、それらはバッファローカルな値になります。 See ファイルにローカルな変数