Emacs-Lisp let文でちょっとはまる
Emacs Lispで現在Emacsで編集中のファイルのフルパス名をクリップボードにコピーし、かつミニバッファに表示するっていう関数を書こうとしたところ、ちょっとはまってしまった。
最初僕が書いたプログラムはこんな感じ。
(defun copy-file-path () (interactive) (let (filename (buffer-file-name)) (kill-new filename) (message "%s" filename)))
これを適当なファイルを開いて「M-x copy-file-path」で実行したところ「Wrong type argument: stringp, nil」なんてエラーが出現。ためしにlet文を消し、filenameと書かれているところを(buffer-file-name)に書き換えるとうまく行く。おそらくlet文にミスがあるんだろうなと推測。だけど、こんな簡単な文のどこに問題があるんだろうと疑問に思ってた。
結局、Emacs Lispの本を読んだところ、letで宣言する変数全体を括弧「( )」で囲まなければいけないんだとわかった。上のプログラムでは、filenameを(buffer-file-name)で初期化しているつもりなんだけど、この上にさらに括弧をつけなきゃいけないようだ。今回の場合はfilenameと言う変数と(buffer-file-name)と言う変数(この関数の実行結果になるのか?)がnilで初期化されて用意されたことになるわけか。
以下のように修正したところ、問題なく動いた。
(defun copy-file-path () (interactive) (let ((filename (buffer-file-name))) (kill-new filename) (message "%s" filename)))