12.17.2 新たなsetfフォーム

このセクションでは、setfが操作できる新たなフォームの定義方法を説明します。

Macro: gv-define-simple-setter name setter &optional fix-return

このマクロは単純なケースでsetfメソッドを簡単に定義することを可能にする。nameは関数、マクロ、スペシャルフォームの名前。nameがそれを更新するための対応するsetter関数をもつなら、このマクロを使用できる(たとえば(gv-define-simple-setter car setcar))。

このマクロは以下のフォームの呼び出しを

(setf (name args...) value)

以下のように変換する。

(setter args... value)

このようなsetfの呼び出しはvalueをリターンするとドキュメントされている。これはcarsetcarでは問題はない。setcarはそれがセットする値をリターンするからである。setter関数がvalueをリターンしない場合には、gv-define-simple-setterfix-return引数に、非nil値を使用すること。これは以下のようなものに展開される

(let ((temp value))
  (setter args... temp)
  temp)

これで正しい結果がリターンされることが保証される。

Macro: gv-define-setter name arglist &rest body

このマクロは上述のフォームより複雑なsetf展開を可能にする。たとえば呼び出すべきシンプルなsetter関数が存在しないときや、もしそれが存在してもplaceフォームとは異なる引数を要求するなら、このフォームを使う必要があるかもしれない。

このマクロは最初にsetf引数フォーム(value args…)arglistにバインドして、その後bodyを実行することによって、フォーム(setf (name args…) value)を展開する。bodyは割り当てを行うLispフォームをリターンして、最終的にはセットされた値をリターンすること。以下はこのマクロの使用例:

(gv-define-setter caar (val x) `(setcar (car ,x) ,val))
Macro: gv-define-expander name handler

展開をより詳細に制御するためにgv-define-expanderマクロが使用できる。たとえばセット可能なsubstringは以下の方法で実装できる:

(gv-define-expander substring
  (lambda (do place from &optional to)
    (gv-letplace (getter setter) place
      (macroexp-let2* (from to)
        (funcall do `(substring ,getter ,from ,to)
                 (lambda (v)
                   (macroexp-let2* (v)
                     `(progn
                        ,(funcall setter `(cl--set-substring
                                           ,getter ,from ,to ,v))
                        ,v))))))))
Macro: gv-letplace (getter setter) place &rest body

マクロgv-letplacesetfのような処理を行うマクロを定義するのに有用。たとえばCommon Lispのincfマクロは以下の方法で実装できる:

(defmacro incf (place &optional n)
  (gv-letplace (getter setter) place
    (macroexp-let2* ((v (or n 1)))
      (funcall setter `(+ ,v ,getter)))))

getterplaceの値をリターンするコピー可能な式にバインドされる。setterは式vを受け取り、placevをセットする新たな式をリターンする関数にセットされる。bodygettersetterを介してplaceを操作するEmacs Lisp式をリターンすること。

詳細はgv.elのソースファイルを参照。

Function: make-obsolete-generalized-variable obsolete-name current-name when

この関数はバイトコンパイラーにジェネリック変数obsolete-nameが陳腐化していると警告させる。current-nameがシンボルなら、obsolete-nameのかわりにcurrent-nameを使用するよう告げるメッセージにより警告が行われる。current-nameが文字列なら、それはメッセージであること。whenはその変数が最初に陳腐化するのがいつかを示す文字列(通常はバージョン番号文字列)。

Common Lispに関する注意: Common Lispは関数としてのsetf、すなわち関数名がシンボルではなくリスト(setf name)であるようなsetf関数の挙動を指定するために別の方法を定義する。たとえば(defun (setf foo) …)は、setffooに適用されるときに使用される関数を定義する。Emacsはこれをサポートしない。適切な展開が定義されていないフォームにsetfを使用するとコンパイル時エラーとなる。Common Lispでは後で関数(setf func)が定義されるのでエラーにならない。


This page has generated for branch:work/emacs-30_69b16e5c63840479270d32f58daea923fe725b90, commit:5e3f74b56ff47b5bcef2526c70f53f749bbd45f6 to check Japanese translation.