スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
Prev.    Category    Next 

変数と setq - 環境設定のための Emacs Lisp 入門

Emacs Lisp 入門の第 3 回です。
今回は変数とそれを設定する setq について解説します。

変数

変数というのは値を格納する入れ物のようなイメージです。
例えば、 tab-width という変数にはタブ幅の値が入っています。 これを *scratch* バッファーで評価してみると次のようになります。
tab-width
8
評価すると入っている値を返します。
elisp_guide_var.png


これは式の中で使うこともできます。
(* 2 tab-width)
16

変数の格納とクオート

次に変数に値を格納してみます。

格納する関数は set です。
(set SYMBOL NEWVAL)
しかし、次のように書くと上手くいきません。
(set tab-width 4)
これは tab-width が評価されて 8 という数字に 4 を入れることになるためです。

そのため、 tab-width の入れ物自体を指定する必要があります。 クオート(quote)すると値の取り出しを行わないようになり、変数自体の指定ができます。 クオートは quote 関数またはそれを省略した '(シングルクオート) で行うことができます。
(set (quote tab-width) 4)
(set 'tab-width 4)
tab-width のような変数をクオートしたものはシンボルと呼ばれています。


変数は入れ物ようなイメージと言いましたが、 プログラミングに詳しい人向けにもう少し elisp の実装に近い形で言い直してみましょう。
tab-width のようなシンボルは elisp 上で一意の文字列で、値と結びつけることができます。 評価すると通常その結び付けられた値が返されます。 しかし、クオートしていると評価が抑制され、シンボル自身を返すということになります。
elisp_guide_symbol.png

シンボルに結び付けられる値は整数、文字列のようなオブジェクト、他のシンボルなどです。
Ruby に詳しい方はそれと同じような感じと思って下さい。 (正確には Ruby が Lisp に似ているのですが)

setq

クオートには、さらに ' も省略する書き方があります。 これが設定でよく使われる setq です。
(setq [SYM VAL]...)
(例) compile や grep の時の Window の幅
(setq compilation-window-height 12)
setq の場合はシンボルと値の2 つずつのセットとして複数指定することもできます。

(例) スクロール設定
(setq scroll-step 1
      scroll-margin 8)

シンボルの作成

すでに Emacs で使われている変数ではなく自分で新しい変数を作ってみます。
(setq foo "bar") ;; "bar"
setq で特に問題なく作成できると思います。 これは逆にいうと tab-with のようにスペルミスして書いていたとしても、 エラーとはならず、気づかないバグとなります。
elisp を書く場合には最初に紹介した M-[Tab] などの補完を使い、 スペルミスをしないようにして下さい。


これはシンボルを使う場合も同様です。
さすがに変数として未定義のものを使えば "値が割り当てられていない(void-variable)" というエラーですが、 クオートしたものは新しいシンボルとしてエラーとはなりません。
foobar ;; エラー
'foobar ;; foobar というシンボル

特殊シンボル

特殊なシンボルを 2 つ紹介します。
シンボル 意味
t 真、 ON
nil 偽、 OFF 、 空

これらは機能の有効、無効を示す変数などに設定します。
;; 検索時には大文字、小文字の区別をしない
(setq case-fold-search t)
;; 置換時に大文字、小文字をそのままで
(setq case-replace nil)
整数の 0, 1 を機能の ON/OFF に使うこともありますが、 基本は t, nil を使い、 nil 以外は真(ON) として扱われることが多いです。

この入門では設定に限っているので、制御文の説明も省いてますが、 参考までにいっておくと、条件分岐(if)の判定では nil 以外は真です。 そのため、 "整数の 0 も真"となります。
 (if 0 "真" "偽") ;; "真"
 (if nil "真" "偽") ;; "偽"

シンボルへの関数と変数の格納

他の言語の経験者にはちょっと奇妙に感じるかもしれませんが、 elisp では同じシンボルを関数、変数のそれぞれで使うことができます。
この場合の入れ物は、箱というよりも複数の引き出しのあるタンスのようなイメージで、 評価時の状況で取り出すときの引き出しを変えます。
elisp_guide_var_lisp2.png

例えば、 モード行に行番号を表示する機能があり、 これには line-number-mode というシンボルを使います。 line-number-mode は変数して評価すると行番号表示のモードが有効かどうかの値を返します。 一方、括弧の先頭に書くと、モードの有効無効を設定する式となります。

*scratch* で試してみると次のようになります。
line-number-mode  ; C-j (括弧がついてないので変数)
nil

(line-number-mode t)
t
なお、 モードの切り替えは式の内部処理でいろいろやっていることが多いので、 xxxx-mode といった変数を直接 setq で設定してはダメです。 式を使ってモードを切り替えて下さい。
ただし、名前の付け方は慣習であってルールではないので、 indent-tabs-mode のように setq で指定する例外もあります。

一つのシンボルが関数にも変数にもなるのは、ちょっと奇妙に感じるかもしれません。 しかし、 elisp でも xxxx-mode といったモードに関するものを除けば、両方とも使うということはほとんどないため、 それほど気にする必要もないと思います。



といいつつ、 elisp の内部に興味ある人向けにもう少し補足しておきます。

シンボルに結び付けられている処理というのは前回紹介したラムダ式(無名関数)です。 defun はラムダ式の定義とシンボルへの設定を一緒に行う便利関数と言えます。

elisp_guide_symbol_lisp2.png

このように同じシンボルで変数と関数の 2 つと結び付けられるのは "Lisp-2 系" といって、 実は Lisp の方言の中でも少数派です。 Scheme, Common Lisp, Clojure といった最近よく使われている Lisp 方言の多くは "Lisp-1 系" といい、 一方しか使えないようになっています。

因みに Lisp-2 系といっていますが、 elisp ではその他に属性リストを結びつけることができ、 シンボル名自身との結合を入れると正確には全部で 4 つのスロットがあります。



関連記事
スポンサーサイト
Prev.    Category    Next 

Facebook コメント


コメント

No title

Common LISPはLISP-2系では?
確か関数と変数で同じシンボル名が使えた気が・・・

コメントの投稿

Font & Icon
非公開コメント

このページをシェア
アクセスカウンター
アクセスランキング
[ジャンルランキング]
コンピュータ
9位
アクセスランキングを見る>>

[サブジャンルランキング]
プログラミング
3位
アクセスランキングを見る>>
カレンダー(アーカイブ)
プルダウン 降順 昇順 年別

09月 | 2017年10月 | 11月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 - - - -


はてな新着記事
はてな人気記事
ブロとも申請フォーム
プロフィール

yohshiy

Author:yohshiy
職業プログラマー。
仕事は主に C++ ですが、軽い言語マニアなので、色々使っています。

はてブ:yohshiy のブックマーク
Twitter:@yohshiy

サイト紹介
プログラミング好きのブログです。プログラミング関連の話題や公開ソフトの開発記などを雑多に書いてます。ただ、たまに英語やネット系の話になることも。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。