次: Variable Scoping, 前: Accessing Variables, 上: Variables
変数の値を変更する普通の方法は、スペシャルフォームsetqを使うことです。
実行時に選択する変数を計算する必要があるときには、
関数setを使います。
このスペシャルフォームは、変数の値を変更するもっとも一般的な方法である。 各symbolに、対応するformの評価結果である新たな値を与える。 シンボルの既存の際、ローカルの束縛を変更する。
setqはsymbolを評価しない。 読者が書いたシンボルに設定する。 この変数は自動的にクォートされるのである。setqの`q'は、『quoted(クォートする)』を表す。フォーム
setqの値は、最後のformの値である。(setq x (1+ 2)) => 3 x ;xはグローバル値を持つ => 3 (let ((x 5)) (setq x 6) ;xのローカル束縛を設定する x) => 6 x ; グローバル値は変更されない => 3最初のformを評価して最初のsymbolに設定し、 つぎに、2番目のformを評価して2番目のsymbolに設定し、 といった具合になることに注意。
(setq x 10 ;xは、yの値を計算するまえに y (1+ x)) ; 設定されることに注意 => 11
この関数は、symbolの値としてvalueを設定し、valueを返す。
setは関数なので、symbolとして書いた式は、 設定するシンボルを得るために評価される。変数の既存の最ローカルの束縛に設定する。 隠されている束縛には影響しない。
(set one 1) error--> Symbol's value as variable is void: one (set 'one 1) => 1 (set 'two 'one) => one (set two 2) ;twoはシンボルoneに評価される => 2 one ; そのため、oneに設定される => 2 (let ((one 1)) ;oneのこの束縛が設定され、 (set 'one 3) ; グローバル値は設定されない one) => 3 one => 2symbol(の評価結果)が実際にはシンボルでないと、 エラー
wrong-type-argumentを通知する。(set '(x y) 'z) error--> Wrong type argument: symbolp, (x y)論理的には、
setはsetqよりもさらに基本的な操作である。 どんなsetqの使い方でも、setで素直に書き直せる。setqは、setを使ってマクロとして定義することも可能である。 しかし、setそのものを使うことは稀であり、 初心者はsetを知る必要がほとんどない。 設定する変数を実行時に選ぶときにのみ有用である。 たとえば、コマンドset-variableは、 ユーザーから変数名を読み取りその変数に設定するので、setを使う必要がある。Common Lispに関した注意: Common Lispでは、setはつねにシンボルの『スペシャル』な、つまり、 動的な値を変更し、文脈上の束縛を無視する。 Emacs Lispでは、すべての変数とすべての束縛は動的であり、setはつねに既存の最ローカルの束縛に作用する。
変数に設定する別の関数は、リストに既存でない要素を追加するように 設計されたものです。
この関数は、elementが変数symbolの値のリストのメンバでなければ、 elementと変数symbolの値をコンスした値を 変数symbolに設定する。 リストを変更してもしなくても結果のリストを返す。 呼び出すまえに、symbolの値はリストであるほうがよい。
引数symbolは暗黙にクォートされない。
add-to-listは、setのように普通の関数であり、setqとは違う。 必要ならば、読者自身でクォートする。
add-to-listの使い方を以下に示します。
(setq foo '(a b))
=> (a b)
(add-to-list 'foo 'c) ;; cを追加する
=> (c a b)
(add-to-list 'foo 'b) ;; なんの効果もない
=> (c a b)
foo ;; fooは変更されている
=> (c a b)
(add-to-list 'var value)に等価な式はつぎのとおりです。
(or (member value var)
(setq var (cons value var)))