Emacs-Lispの変数の扱いについて

Posted by Tatsuyano on Thu, Sep 20, 2012
In
Tags emacs

やさしいEmacs-Lisp講座(改訂版)の勉強メモ。

動的スコープ(P21)

変数(let*以外)は動的スコープとして扱われる。
つまり一度変数を宣言すると、その変数はどこからでも参照できてしまう。

変数名の衝突(P19)

Emacs-Lispは処理系全体(読み込んでいるすべてのプログラム)で一つの名前空間しかない。
なのでグローバル変数にはパッケージ固有のプレフィックスをつける。

defvar(P19)

defvarで変数を宣言すると、その変数の値は、defvarで再度値を代入しても更新されない(しかしsetqなどで値の代入された場合は更新されてしまう)。
Emacs-Lispでは「定数宣言」のように使っていく。

(defvar dvar 1 "実験用") ;; -> 1
(defvar dvar 2)         ;; -> 1 値が上書きされない
(setq dvar 3)           ;; -> 3 defvar以外で宣言(代入)された場合は上書きされてしまう。

set,setq(P18)

変数の代入(宣言)を行う。setqのほうは同時に複数の変数を代入できる。

(set 'foo 5)
(setq aa 3 bb 2 cc 4)

let(P20)

let式の中で初めて宣言された変数は、let式外(グローバル領域)では参照できない。
関数内だけで参照したい(ローカル変数として使いたい)場合に用いる。
グローバル変数をlet式内で一時的に変えたい場合に用いる。
本体すべてを評価したあとで、最後に評価した値を返す。

;書式—————
;(let (変数リスト) |
; 本体)      |
; ——————

(setq foo 5);; -> 5

(let ((foo 3) (fuga foo))
  fuga);; -> 5 fugaがグローバル変数のfooで初期化されるため

(let ((foo 3))
  foo);; -> 3 let式のfooで初期化されるため

foo  ;; -> 5 let式で値が更新(代入)されても、値に影響されない
fuga ;; -> error let式内で宣言された変数のため

let*(P21)

(let* ((foo 3) (fuga foo))
  fuga);; -> 3 fugaがlet式のfooで初期化されるため

(let* ((foo 3))
  foo);; -> 3 let式のfooで初期化されるため