“名前変更シンボル(renamed symbols)”と呼ばれることもあるシンボルのショートハンド(shorthands: 速記、簡略表記)とは、Lispソースで目にする抽象形式です。これらは正規の抽象形式と類似していますが、Lispリーダーがそれらに遭遇した際に別の通常はもっと長いプリント名(print name)を生成する点が異なリます(シンボルの構成要素を参照)。
ショートハンドを意図するシンボルの完全名にたいする略語(abbreviating)と考えることは有益です。その点を除けばAbbrevシステム(abbrevとabbrev展開を参照)とショートハンドを混同しないでください。
ショートハンドによりEmacs Lispのネームスペース作法(namespacing
etiquette)にしたがうことが容易になります。すべてのシンボルは単一のobarray (シンボルの作成とinternを参照)に格納されるので、一般的にプログラマーはシンボル名それぞれにたいして出自ライブラリー名をプレフィクスとして付加します。たとえば関数text-property-search-forward
とtext-property-search-backward
はどちらもtext-property-search.elライブラリーに属しています(ロードを参照)。シンボル名に正しくプレフィクスを付加することによって、異なるライブラリーに属する別のことを行う同一名シンボル間でのクラッシュを効果的に回避できます。しかしこれを実践してしばらくすると、一般的にはタイプしにくく読み難い、非常に長いシンボル名となります。これらの問題をショートハンドは明快な方法により解決します。
この変数の値は要素が(shorthand-prefix
.
longhand-prefix)
という形式であるようなalist。それぞれの要素はLispリーダーにたいして、shorthand-prefixで始まるすべてのシンボルを、longhand-prefixで始まるシンボルとして読み取るよう指示する。
この変数はファイルローカル変数としてのみセットできる(Local Variables in Files in The GNU Emacs Manualを参照)。
以下は架空の文字列操作ライブラリーsome-nice-string-utils.elでショートハンドを使用する例です。
(defun some-nice-string-utils-split (separator s &optional omit-nulls) "match-dataを保存する`split-string'の変種" (save-match-data (split-string s separator omit-nulls))) (defun some-nice-string-utils-lines (s) "文字列Sを改行文字で分割して文字列リストにする" (some-nice-string-utils-split "\\(\r\n\\|[\n\r]\\)" s))
見ての通りタイプするシンボル名が非常に長いので、このコードを読んだり開発するのはとても退屈です。これの緩和にショートハンドが使用できます。
(defun snu-split (separator s &optional omit-nulls) "match-dataを保存する`split-string'の変種" (save-match-data (split-string s separator omit-nulls))) (defun snu-lines (s) "文字列Sを改行文字で分割して文字列リストにする" (snu-split "\\(\r\n\\|[\n\r]\\)" s)) ;; Local Variables: ;; read-symbol-shorthands: (("snu-" . "some-nice-string-utils-")) ;; End:
この2つの例が異なるように見えても、これらをLispリーダーが処理した後はまったく同じです。どちらもインターン(シンボルの作成とinternを参照)される同一のシンボルへと導かれます。したがって2つのファイルのどちらをバイトコンパイルしても、同じ結果が得られます。2つ目のバージョンのショートハンドsnu-split
とsnu-lines
はobarrayにインターンされません。これはショートハンド使用箇所にポイントを移動して、ポイント位置のシンボルの真のシンボル名のヒントをElDoc
(Local Variables in Files in The GNU
Emacs Manualを参照)がエコーエリアに表示するのを待つことで容易に確認できます。
read-symbol-shorthands
はファイルローカル変数なので、some-nice-string-utils-lines.elに依存する複数のライブラリーが同一のシンボルを異なるショートハンドで参照したり、あるいはショートハンドをまったく使用せずに参照することが可能になります。次の例ではmy-tricks.elライブラリーがsnu-
ではなく、sns-
というプレフィクスを使用してシンボルsome-nice-string-utils-lines
を参照しています。
(defun t-reverse-lines (s) (string-join (reverse (sns-lines s)) "\n") ;; Local Variables: ;; read-symbol-shorthands: (("t-" . "my-tricks-") ;; ("sns-" . "some-nice-string-utils-")) ;; End:
同じファイル内で一方がもう一方のプレフィクスであるようなショートハンドが2つある場合には、最初に長いほうのショートハンドが試されることに注意してください。これはファイルのローカル変数セクションにおけるショートハンドの指定順序とは無関係に行われます。
'( t//foo ; reads to 'my-tricks--foo', not 'my-tricks-/foo' t/foo ; reads to 'my-tricks-foo' ) ;; Local Variables: ;; read-symbol-shorthands: (("t/" . "my-tricks-") ;; ("t//" . "my-tricks--") ;; End:
ショートハンド変換適用を管理するにあたって2つの例外があります:
-
や/=
をショートハンドプレフィクスとして使用するのは可能だが、それらの名前は算術の関数をシャドーしない。