============================================== 2000.07.27 発行 =========
         極私的 Emacs カスタマイズ紹介マガヂン
            Emacs をわたし色に染めて♪
------------------------------------------------------------------------
                   第 21 回 マクロのための文法解説I
------------------------------------------------------------------------
※あなたのカスタマイズをぜひ教えてください。一般的なものから、他の人は
 絶対にしないような「外道」なものまで、何でも結構です。

※解除の方法は、このメールの末尾をごらんください。
========================================================================

	はじめてのかたも、そうでないかたも、こんにちは。
	でるもんた・いいじまです。

	前回の発行からもう 6 か月近くが経とうとしています。
	実は、前回の発行後、就職活動がはじまりまして(^^;)、今頃にはもう
	内定をもらってノホホンとしているはずが、実際にはうまくいかずに
	ノイローゼに陥り、鬱病の一歩手前にまでなってしまいました(診断名は
	「反応性鬱状態」だそうです)。今もまだ本調子ではありません。

	【参考】全然このマガジンとは関係ありませんが、鬱病について興味の
	    ある方は http://www.so-net.ne.jp/vivre/kokoro/ へどうぞ。

	【余談】で、就職活動とノイローゼが一段落したら、その体験記をまた
	    メールマガジンにして発行しようかと思っていたりします(^^;)

	その間ずっとお休みしていたわけですが、まぐまぐさんから「半年間も
	発行していないから 8 月 1 日に消すぞ」とせかされて、慌てて書いて
	おります。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆はじめての方へお断り☆

	このマガジンがはじめての方の中には、『日経 Linux』8 月号で私の
	サイトを紹介されて見に来られたという方が多いと思います。

	この記事では Emacs 20.x の話が中心なのですが、私はいまだに Emacs
	19.34(Mule 2.3)を使っています。この記事では、私はもう Emacs 20.x
	に移行したと取れるような書き方になっておりますが、実際にはまだ
	Mule 2.3 が中心で、Emacs 20.x はたまにしか使っておりません。
	したがって、このマガジンの対象は、
		○原則として、Mule 2.3 と Emacs 20.x の共通部分を扱う
		○Mule 2.3 と Emacs 20.x で共通でない部分(多国語の扱い
		 方など)は、極力両方を挙げるようにするが、Mule 2.3 での
		 方法だけしか扱わないことがある
	ということでご了承ください。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆今回のお題☆

	今回から何回かは、実際的なところからは離れて、文法の話をします。

	というのは、いままでは「リスト」「quote」「ドット・ペア」といった
	文法要素にはあまり触れないできたのですが、マクロを書く上では、
	このへんの文法の知識がどうしても必要になってきてしまい、これらを
	おざなりにしたままではマクロの解説もしにくいということがはっきり
	してきたからです。

	今回はまず、デバッグのためのコマンドの解説と、「quote」について
	説明します。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆はじめに - デバッグの際に有用なコマンドをいくつか☆

	マクロを組むときには、記述してある内容を 1 ステップずつ順番に
	確認したい、ということがあります。まずは、こういった場合に便利な
	コマンドをいくつかご紹介します。

◇eval-last-sexp(標準キー操作だと C-x C-e、飯嶋式だと M-o C-x C-e)

	「sexp」ってなんじゃらほい、と思うかも知れませんが、これは
	S expression の略です。日本語ではそのままずばり S 式と言います。
	じゃあ S 式ってなあに、ということになりますが、深く考えずに、
	要するに今までに出てきたような、やたらめったら括弧の出てくる、
	Lisp 言語での「普通の」式のことだと思ってもらえばかまいません。

	【余談】ちなみに、Lisp 言語では、末尾の p は「○○か否か?」という
	    意味になります。たとえば、stringp という関数は「文字列か
	    否か」という意味で、引数が文字列ならば t を、そうなければ
	    nil を返します。そこから類推すると、sexp というのは「sex か
	    否か」ということになってしまうのですが、あいにく Lisp には
	    sex という専門用語はありません。

	このコマンドを実行すると、カーソル位置の直前までで終わる式を評価
	(evaluate;eval というのはその省略形ですね)し、それをミニバッファ
	(画面の一番下の行)に表示します。

	たとえば、「(+ 3 4)」と入力し、カーソルをこの閉じ括弧の直後に
	置いて C-x C-e(M-o C-x C-e)を押すと、画面下に 7 と表示されます。

	あるいは、「(or (> 4 3) (> 5 7))」の最後の閉じ括弧の直後にカーソル
	を置いて C-x C-e(M-o C-x C-e)を押すと、今度は t と表示されるはず
	です。

	なお、このとき、カーソルを (> 5 7) の直後、つまり最後の閉じ括弧の
	上に置いて C-x C-e(M-o C-x C-e)を押すと、nil と表示されます。
	これは、このコマンドが「カーソル位置の直前までで終わる式」、つまり、
	「(> 5 7)」の部分だけを評価するからです。

◇eval-last-sexp の応用

	これを使って、変数の内容を確認したり、ちょっとしたマクロをその場で
	実行したりすることができます。第 1 回でご紹介した内容からいくつか
	ご紹介します。

	まず、line-number-mode と入力し、カーソルをその e の直後に置いて、
	C-x C-e(M-o C-x C-e)と入力します。そうすると、変数 line-number-
	mode の値が表示されます。これは、この場合、「カーソル位置の直前
	までで終わる式」というのが、括弧のついた式ではなく、単に変数名
	だけが書いてあるものなので、その変数の値が表示されるのです。

	つづいて、(setq line-number-mode t) と入力し、カーソルを括弧の
	直後に置いたままで C-x C-e(M-o C-x C-e)を入力すると、t と表示
	されます。この場合は、setq 文ですので変数への代入が行われ、代入
	された値である t が表示されるのです。

◇eval-region、eval-buffer

	これは、範囲指定した範囲(region)、あるいは編集中のファイル
	(バッファ=buffer)全体を評価するコマンドです。たとえば、
	適当なバッファに

		(setq line-number-mode t)
		(setq column-number-mode t)

	と書き、この 2 行を範囲指定して M-x eval-region RET とすると、
	その 2 行が実行されます。

	これはたとえば、~/.emacs を編集後に、書き換えた部分だけを再実行
	するために使っています。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆quote って?☆

	いままで、コマンド名などの頭にアポストロフィ「'」をつける、という
	ケースが何度かありました。たとえば、

		(global-set-key "\C-i" 'tab-to-tab-stop)

	といった具合です。このアポストロフィの意味が今回のテーマです。

◇アポストロフィは quote の省略形

	このアポストロフィは、quote という関数の省略形です。つまり、
	「'なんたらかんたら」と「(quote なんたらかんたら)」は全く同じ
	意味になります。ですので、上の文は、

		(global-set-key "\C-i" (quote tab-to-tab-stop))

	と書いてもかまわないことになります。

◇quote=評価前の値/例 1: 変数の値の場合

	さて、この quote は、「その引数になっている式を評価する前の値」
	という意味になります。たとえば、

		(setq a (+ 1 2))

	とすると、変数 a に代入される値は、(+ 1 2) という式を評価した結果、
	つまり 3 になります。いっぽうで、

		(setq b (quote (+ 1 2)))

	または

		(setq b '(+ 1 2))

	とすると、変数 b には、「(+ 1 2)」という式そのものが代入されること
	になります。あるいは、

		(setq c 'd)

	とすると、変数 c には「変数名 d」が代入されることになります。

	【補足】これらの結果は、eval-last-sexp で実行したときにミニバッファ
	    に表示される結果や、「M-x describe-variable RET a RET」と
	    いうコマンドで調べることができます。実際、describe-variable
	    で a、b、c の値を表示させてみると、
	    	a's value is 3
	    	b's value is (+ 1 2)
	    	c's value is d
	    と表示されます。

◇例 2: global-set-key の場合

	さて、

		(global-set-key "\C-i" tab-to-tab-stop)

	のように、コマンド名の前のアポストロフィを省略すると、この「tab-to-
	tab-stop」の部分は「変数 tab-to-tab-stop の中身」という意味になって
	しまいます。tab-to-tab-stop という名前は変数としては存在しないので、
	これはエラーになってしまいます。逆に言うと、

		(setq a 'tab-to-tab-stop)

	として変数 a に「コマンド名 tab-to-tab-stop」を記録しておいてから、

		(global-set-key "\C-i" a)

	のように設定することが可能です。

◇例 3: リストの場合

	第 6 回で

		(setq tab-stop-list '(1 3 7 15 31))

	という式が出てきました。これは、変数 tab-stop-list に「リスト
	(1 3 7 15 31)」を代入しています。ここでもしアポストロフィをとって
	しまうと、Emacs は「(1 3 7 15 31) という式を評価した結果」を変数
	tab-stop-list に代入しようとします。「(1 3 7 15 31)」という式は、
	「1 という名前の関数に、3 7 15 31 という引数を与えて呼び出した結果」
	という意味になりますが、当然ながら「1」という名前の関数はないので、
	エラーになります。

◇リストに使う場合は注意が必要 --- list 関数との違い

	リストを作るには、そのものずばり、list という名前の関数を使う方法が
	あります。たとえば、上の例ならば

		(setq tab-stop-list (list 1 3 7 15 31))

	としてもかまいません。

	では、list 関数とアポストロフィとは何が違うのかというと、list 関数
	では、引数の内容が評価されます。たとえば、

		(setq a 3)
		(setq L1 (list 1 2 a))
		(setq L2 '(1 2 a))

	とすると、L1 は、まず a の値を 3 と評価し、(1 2 3) というリストを
	作ります。M-x describe-variable RET L1 RET とすると、L1's value is
	(1 2 3) と表示されます。

	一方で、L2 のほうは、括弧の中を一切評価せず、「1」「2」「変数名 a」
	からなる「(1 2 a)」というリストを作ります。M-x describe-variable
	RET L2 RET とすると、L2's value is (1 2 a) と表示されます。

	ですから、リストを作る場合は、
		○リストの各要素が「式の計算結果」であってほしい場合は
		 list 関数を使う
		○リストの各要素が「変数名・コマンド名」「式そのもの」で
		 あってほしい場合は、基本的にはアポストロフィを使う
	という使い分けになります。

	では、「式の計算結果」と「変数名・コマンド名」の両方を使いたい
	場合はどうするのかというと、基本的には list 関数を使い、変数名・
	コマンド名の頭に個別にアポストロフィをつけることになります。
	たとえば、

		(setq L3 (list 1 (+1 3) 'a))

	とすると、「L3's value is (1 4 a)」となります。

◇例 4: 第 13 回より

	第 13 回で出てきた

		(define-key menu-bar-help-menu [tutorial-for-mule]
		    '("Tutorial for Mule" . help-with-tutorial-for-mule)
		)

	では、括弧の前にいったんアポストロフィがついているので、コマンド名
	「help-with-tutorial-for-mule」の前にはあらためてアポストロフィを
	つける必要がありません(つけてはいけません)。逆に、アポストロフィを
	この位置につけたい場合は、この場合はリストではなくドットペア(二つの
	要素の間にピリオド「.」が入ってます;リストとドットペアの違いは次回
	説明します)なので list のかわりに cons 関数を使って、

		(define-key menu-bar-help-menu [tutorial-for-mule]
		    (cons "Tutorial for Mule" 'help-with-tutorial-for-mule)
		)

	とすることになります。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆あとがき☆

	今回は非常にわかりにくい内容になってしまいました。もしわからない
	内容がありましたら、遠慮なく L94102@mail.ecc.u-tokyo.ac.jp まで
	メールをください。可能な範囲でお答えしたいと思います。

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
☆次回予告☆

	今後は、この今回の続編として、「アトムとは何か」「リスト」「ドット
	ペア(dotted pair)」を扱います。次の発行がいつになるのかはわかり
	ませんが…

	それではまた♪

========================================================================
極私的 Emacs カスタマイズ紹介マガジン Emacs をわたし色に染めて♪

☆発行人☆

        でるもんた・いいじま <L94102@mail.ecc.u-tokyo.ac.jp>
                        http://user.ecc.u-tokyo.ac.jp/~l94102/emacs/

                ※このメールマガジンで取り上げてほしいテーマ、ご意見など
                 ありましたら、上のメールアドレスまでお気軽にどうぞ。

☆配信☆
        このメールマガジンは、「インターネットの本屋さん・まぐまぐ」を
        利用して配信しています。
                http://www.mag2.com     (マガジン ID=0000013484)

☆バックナンバー・登録解除・メールアドレス変更は☆

        上記のホームページまでどうぞ。
        なお、手動での登録解除は行っておりませんのでご了承下さい。
=========================================================================

Copyright © IIJIMA Hiromitsu aka Delmonta, 2016/03/10 15:09 JST
これは「古文書」です。 古くなった情報も原則未修正で保存していますのでご注意ください。

古文書本館トップ | 電脳外道学会