« プログラミングを始めるには(22) | Main | プログラミングを始めるには(24) »

August 20, 2014

プログラミングを始めるには(23)

前囘は「こんな關數を書いてはいけません!」という見本のような關數を書いたところで終わった。正確には「elispプログラムの中でこんなファンクションを使ってはいけません」と書くべきかもしれない。では具體的に何をどうすれば良いかを說明するために、正解例を示す。

(defun edit-new-command ()
  "こんな關數なら書いてイイかも"
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (forward-line 5)
    (let* ((beg (point))
	   (end (progn (forward-line) (point)))
	   (string (buffer-substring-no-properties beg end)))
      (delete-region beg end)
      (goto-char (point-max))
      (insert string))))

人によっては「なんじゃこりゃ?!」と思われるかもしれない。これは、ホントはこのように書かなければならないという一例だ。これだとKeyboard Macro Editorで表示した手順と全然違っている。

最初に書いた惡い例では、すべての手順にコマンドファンクション使用している。まずはこれが良くない。さらに「C-h f」でbeginning-of-bufferのヘルプを讀むと、「Don't use this command in Lisp programs!」と書かれている。end-of-bufferも同樣だ。next-lineについては「If you are thinking of using this in a Lisp program, consider using `forward-line' instead.」と書かれている。ひょっとしたら異論がある人も居るかもしれないが、ヘルプに「interactive ~ function」として定義されているファンクションは使わない方が良い。これはelispプログラムの中で使用するのではなく、Emacsの編集操作を目的として定義されているファンクションだからだ。

(defun edit-new-command-2 ()
  "慣れていない人はたぶんこう書く"
  (interactive)
  (goto-char (point-min))
  (forward-line 5)
  (setq start-position (point))
  (forward-line)
  (setq end-position (point))
  (setq string (buffer-substring start-position end-position))
  (delete-region start-position end-position)
  (goto-char (point-max))
  (insert string))

私も最初はそうだったが、慣れていないうちはたぶんこんな書き方になるのだろう。これでも最初のコマンドの羅列よりは良いのだが、ユーザのバッファ内のテキストを編集する場合は、まずユーザの編集セッションを壞してはいけないことに注意する。ここではカーソルを移動しているので、プログラム實行前と後ではカーソルの位置が變わってしまう。最初の惡い例では、beginning-of-lineend-of-lineによりユーザのmark-ringを、kill-lineによりユーザのkill-ringを變更してしまう。良い例ではこれを防ぐためにsave-excursionを使って、現在の編集セッションから脫線し、フォームを拔けるときに編集セッションを復元する。こうすることでこのコマンドを實行した後もユーザは違和感なく編集を繼續できる。この例の場合は1個のバッファの中だけで處理が終わるが、プログラムの中でバッファを切り替える場合は、脫線フォームを使わないと、プログラムが終了するときにたまたま處理對象としていたバッファが表示された狀態で終わることになる。これでは「立つ鳥後を濁さず」の原則に反することになる。

あとはstart-positionとかend-positionとかで、あまり意識せずに?グローバル變數を使ってしまっている。これもユーザが別の處理で同じグローバル變數を使っていた場合に問題になる。なので變數は出來るだけローカルバインディングを使用した方が良い。通常、defunDoc Stringに「こんな關數なら書いてイイかも」とか「慣れていない人はたぶんこう書く」などとは書かない。これはこの記事の中だけの冗談である。本來はそのファンクションの說明をヘルプを參考にして書くべきだ。

|

« プログラミングを始めるには(22) | Main | プログラミングを始めるには(24) »

Comments

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/74224/60183031

Listed below are links to weblogs that reference プログラミングを始めるには(23):

« プログラミングを始めるには(22) | Main | プログラミングを始めるには(24) »