概要
私の受ける印象では,Emacs Lispを敬遠している人が多すぎる.多くの場合,この理由は,(1) Lispが嫌い,(2) Emacsが嫌い,のいずれかである.後者は思想の違いなのでどうしようも無いが,前者の理由で使わないのであれば,損をしていると私は考える.
ここでは,私がEmacs Lispを実際に利用する場面を,ケーススタディとして示す.Lispが嫌いな方が退屈しないよう,Lispの構文については触れない.
Emacs Lispを実行するには
まず,Emacs Lispを実行する方法を知らなければならない.手っ取り早く実行する方法として,次の2種類の方法がある.この他にも数種類の方法があるが,ここでは省略する.
*scratch*バッファを使う
Emacsを引数なしで起動すると,*scratch*バッファが開かれる.このバッファで\C-jと入力すると,カーソルの直前にあるLispを実行する.
例えば次のコードは,hogeと出力するものである.
(message "hoge")
この「)」の次にカーソルを合わせて\C-jを入力すれば,カーソル位置に"hoge"と出力される.
(message "hoge")
[ここにカーソルを置いて\C-jと入力]
=> "hoge"
eval-last-sexp関数を使う
上記のコードにて,上記と同様「)」の次にカーソルを合わせる.そして,\C-x\C-eと入力すると,直前のLispを実行する.
入力シーケンス \C-x\C-eは,M-x eval-last-sexpと同様.上記と同様,カーソル位置の手前にあるLispを評価する. *scratch*バッファとの違いは,実行結果がミニバッファに表示される点,一般のファイル(*scratch*バッファ以外)でも実行できる点,である.
ケーススタディ
簡単な計算をする
Emacs Lispを用いると,簡単な四則演算が可能.
例えば,次のLispは1日の秒数を計算する.
(* 60 60 24)
=> 86400
また,あるファイルに次のような数値の羅列が保存されているとする.
34
42
...
56
これらの数値の合計を求めるには,前後にLispを加えれば良い.
(+
34
42
...
56
)
勿論,複雑な計算も可能.次は,1から1000までの数値の合計を計算する.ちなみに,1からNまでの合計はN*(N+1)/2.
(/ (* 1000 (+ 1000 1)) 2)
=> 500500
少数が含まれれば浮動小数点演算,整数のみであれば整数演算となる.
(/ 10 3)
=> 3
(/ 10.0 3)
=> 3.333333333
文字列を自動生成する
例えば,C言語で次の定義文を書くとする.
#define HOGE0 100
#define HOGE1 101
#define HOGE2 102
#define HOGE3 103
4行であれば大した問題ではないが,これが100行になったら,あるいは頻繁に行数が変わるとすれば,さすがに自力で書くのはしんどい.
ここでEmacs Lispが活躍する.次のEmacs Lispで,上記の定義文を生成できる.
(let ((i 0))
(while (< i 4)
(insert (format "#define HOGE%d %d\n" i (+ 100 i)))
(setq i (+ i 1))))
かなりラフに説明すると,次のようになる.(1) letでローカル変数iを定義.(2) whileでiが0から3までループ.(3) insertでカレントバッファに1行ずつ出力.(4) setqでiをインクリメント.
この方法の良いところは,Cのコードを書いているエディタ上に自動化のコードを書くことができ,その場で実行できるところにある.
これだけでは意味がわからないので,Emacs Lispを使用しない場合を例に示そう.コードを生成自動するには,jotやseqを使う,またはrubyやperlなどのスクリプトを組む,といった方法がある.これらの方法には,スクリプトファイルが増える,という問題点がある.私も経験があるが,スクリプトファイルが散乱すれば,管理することが困難になる.何のスクリプトファイルが何をするものであったのか,作者でも時間が経てば忘れてくるのだ.
一方,Emacs Lispであれば,Cのソースコード内に記述できる.さらに,次のようにCの構文でコメントアウトしておく.
/*** Cソースファイル ***/
/*
(let ((i 0))
(while (< i 4)
(insert (format "#define HOGE%d %d\n" i (+ 100 i)))
(setq i (+ i 1))))
*/
こうすることで,(1) 新たにスクリプトファイルが増えることなく,(2) 必要な箇所に必要なEmacs Lispのコードを配置し,(3) Cのコンパイルも問題なく通す,ことができるのである.
ちなみに,おわかりだと思うが,上記コードは,次のように4を100に変更することで,100行の出力が可能.
/*
(let ((i 0))
(while (< i 100)
(insert (format "#define HOGE%d %d\n" i (+ 100 i)))
(setq i (+ i 1))))
*/