Next: , Previous: , Up: Customization Types   [Contents][Index]


15.4.2 複合型

適切なシンプル型がなければ複合型(composite types)を使用することができます。複合型は特定のデータにより、他の型から新しい型を構築します。指定された型やデータは、その複合型の引数(argument)と呼ばれます。複合型は通常は以下のようなものです:

(constructor arguments…)

しかし以下のように引数の前にkeyword-valueペアーを追加することもできます。

(constructor {keyword value}arguments…)

以下のテーブルに、コンストラクター(constructor)と複合型を記述するためにそれらを使用する方法を示します:

(cons car-type cdr-type)

値はコンスセルでなければならずCARcar-typeCDRcdr-typeに適合していなければならない。たとえば(cons string symbol)は、("foo" . foo)のような値にマッチするデータ型となる。

カスタマイゼーションバッファーでは、CARCDRはそれぞれ特定のデータ型に応じて個別に表示と編集が行われる。

(list element-types…)

値はelement-typesで与えられる要素と数が正確に一致するリストでなければならず、リストの各要素はそれぞれ対応するelement-typeに適合しなければならない。

たとえば(list integer string function)は3つの要素のリストを示し、1つ目の要素は整数、2つ目の要素は文字列、3つ目の要素は関数である。

カスタマイゼーションバッファーでは、各要素はそれぞれ特定のデータ型に応じて個別に表示と編集が行われる。

(group element-types…)

これはlistと似ているが、Customバッファー内でのテキストのフォーマットが異なる。listは各要素の値をそのタグでラベルづけするが、groupはそれを行わない。

(vector element-types…)

これはlistと似ているが、リストではなくベクターでなければならない。各要素はlistの場合と同様に機能する。

(alist :key-type key-type :value-type value-type)

値はコンスセルのリストでなければならず、各セルのCARはカスタマイゼーション型key-typeのキーを表し、同じセルのCDRはカスタマイゼーション型value-typeの値を表す。ユーザーはkey/valueペアーの追加や削除ができ、各ペアのキーと値の両方を編集することができる。

省略された場合のkey-typevalue-typeのデフォルトはsexp

ユーザーは指定されたkey-typeにマッチする任意のキーを追加できるが、:options(Variable Definitionsを参照)で指定することにより、あるキーを優先的に扱うことができる。指定されたキーは、(適切な値とともに)常にカスタマイゼーションバッファーに表示される。またalistにkey/valueを含めるか、除外するか、それとも無効にするかを指定するチェックボックスも一緒に表示される。ユーザーは:optionsキーワード引数で指定された値を変更できない。

:optionsキーワードにたいする引数は、alist内の適切なキーにたいする仕様のリストであること。これらは通常は単純なアトムであり、それらは自身を意味します。たとえば:

:options '("foo" "bar" "baz")

これは名前が"foo""bar""baz"であるような3つの既知のキーがあることを指定し、それらは常に最初に表示される。

たとえば"bar"キーに対応する値を整数だけにするというように、特定のキーに対して値の型を制限したいときがあるかもしれない。これはリスト内でアトムのかわりにリストを使用することにより指定することができる。前述のように1つ目の要素はそのキー、2つ目の要素は値の型を指定する。たとえば:

:options '("foo" ("bar" integer) "baz")

最後にキーが表示される方法を変更したいときもあるだろう。デフォルトでは:optionsキーワードで指定された特別なキーはユーザーが変更できないので、キーは単にconstとして表示される。しかしたとえばそれが関数バインディングをもつシンボルであることが既知なら、function-itemのようにあるキーの表示のためにより特化した型を使用したいと思うかもしれない。これはキーにたいしてシンボルを使うかわりに、カスタマイゼーション型指定を使用することにより行うことができる。

:options '("foo"
           ((function-item some-function) integer)
           "baz")

多くのalistはコンスセルのかわりに2要素のリストを使用する。たとえば、

(defcustom cons-alist
  '(("foo" . 1) ("bar" . 2) ("baz" . 3))
  "Each element is a cons-cell (KEY . VALUE).")

のかわりに以下を使用する

(defcustom list-alist
  '(("foo" 1) ("bar" 2) ("baz" 3))
  "Each element is a list of the form (KEY VALUE).")

リストはコンスセルの最上位に実装されているため、上記のlist-alistをコンスセルのalist(値の型が実際の値を含む1要素のリスト)として扱うことができる。

(defcustom list-alist '(("foo" 1) ("bar" 2) ("baz" 3))
  "Each element is a list of the form (KEY VALUE)."
  :type '(alist :value-type (group integer)))

listのかわりにgroupを使用するのは、それが目的に適したフォーマットだという理由だけである。

同様に以下のようなトリックの類を用いることにより、より多くの値が各キー連づけられたalistを得ることができる:

(defcustom person-data '(("brian"  50 t)
                         ("dorith" 55 nil)
                         ("ken"    52 t))
  "Alist of basic info about people.
Each element has the form (NAME AGE MALE-FLAG)."
  :type '(alist :value-type (group integer boolean)))
(plist :key-type key-type :value-type value-type)

このカスタマイゼーション型はalist(上記参照)と似ているが、(1)情報がプロパティーリスト(Property Listsを参照)に格納されていて、(2)key-typeが省略された場合のデフォルトはsexpではなくsymbolになる。

(choice alternative-types…)

値はalternative-typesのうちのいずれかに適合しなければならない。たとえば(choice integer string)では整数か文字列が許容される。

カスタマイゼーションバッファーでは、ユーザーはメニューを使用して候補を選択して、それらの候補にたいして通常の方法で値を編集できる。

通常はこの選択からメニューの文字列が自動的に決定される。しかし候補の中に:tagキーワードを含めることにより、メニューにたいして異なる文字列を指定できる。たとえば空白の数を意味する整数と、その通りに使用したいテキストにたいする文字列なら、以下のような方法でカスタマイゼーション型を記述したいと思うかもしれない

(choice (integer :tag "Number of spaces")
        (string :tag "Literal text"))

この場合のメニューは‘Number of spaces’と‘Literal text’を提示する。

const以外のnilが有効な値ではない選択肢には、:valueキーワードを使用して有効なデフォルト値を指定すること。Type Keywordsを参照のこと。

複数の候補によりいくつかの値が提供されるなら、カスタマイズは適合する値をもつ最初の候補を選択する。これは常にもっとも特有な型が最初で、もっとも一般的な型が最後にリストされるべきことを意味する。以下は適切な使い方の例である

(choice (const :tag "Off" nil)
        symbol (sexp :tag "Other"))

この使い方では特別な値nilはその他のシンボルとは別に扱われ、シンボルは他のLisp式とは別に扱われる。

(radio element-types…)

これはchoiceと似ているが、選択はメニューではなくラジオボタンで表示される。これは該当する選択にたいしてドキュメントを表示できる利点があるので、関数定数(function-itemカスタマイゼーション型)の選択に適している場合がある。

(const value)

値はvalueでなければならず他は許容されない。

constは主にchoiceの中で使用される。たとえば(choice integer (const nil))では整数かnilが選択できる。

choiceの中では:tagとともにconstが使用される場合がある。たとえば、

(choice (const :tag "Yes" t)
        (const :tag "No" nil)
        (const :tag "Ask" foo))

これはtがyes、nilがno、fooが“ask”を意味することを示す。

(other value)

この選択肢は任意のLisp値にマッチできるが、ユーザーがこの選択肢を選択したら値valueが選択される。

otherは主にchoiceの最後の要素に使用される。たとえば、

(choice (const :tag "Yes" t)
        (const :tag "No" nil)
        (other :tag "Ask" foo))

これはtがyes、nilがno、それ以外は“ask”を意味することを示す。ユーザーが選択肢メニューから‘Ask’を選択したら、値fooが指定される。しかしその他の値(tnilfooを除く)ならfooと同様に‘Ask’が表示される。

(function-item function)

constと同様だが値が関数のときに使用される。これはドキュメント文字列も関数名と同じように表示する。ドキュメント文字列は:docで指定した文字列かfunction自身のドキュメント文字列。

(variable-item variable)

constと同様だが値が変数名のときに使用される。これはドキュメント文字列も変数名と同じように表示する。ドキュメント文字列は:docで指定した文字列かvariable自身のドキュメント文字列。

(set types…)

値はリストでなければならず指定されたtypesのいずれかにマッチしなければならない。

これはカスタマイゼーションバッファーではチェックリストとして表示されるので、typesはそれぞれ対応する要素を1つ、あるいは要素をもたない。同じ1つのtypesにマッチするような、異なる2つの要素を指定することはできない。たとえば(set integer symbol)はリスト内で1つの整数、および/または1つのシンボルが許容されて、複数の整数や複数のシンボルは許容されない。結果としてset内でintegerのような特化していない型を使用するのは稀である。

以下のようにconst型はset内のtypesでよく使用される:

(set (const :bold) (const :italic))

alist内で利用できる要素を示すために使用されることもある:

(set (cons :tag "Height" (const height) integer)
     (cons :tag "Width" (const width) integer))

これによりユーザーにオプションでheightとwidthの値を指定させることができる。

(repeat element-type)

値はリストでなければならず、リストの各要素は型element-typeに適合しなければならない。カスタマイゼーションバッファーでは要素のリストとして表示され、‘[INS]’と‘[DEL]’ボタンで要素の追加や削除が行われる。

(restricted-sexp :match-alternatives criteria)

これはもっとも汎用的な複合型の構築方法である。値はcriteriaを満足する任意のLispオブジェクト。criteriaはリストで、リストの各要素は以下のうちのいずれかを満たす必要がある:

たとえば、

(restricted-sexp :match-alternatives
                 (integerp 't 'nil))

これは整数、tnilを正当な値として受け入れる。

カスタマイゼーションバッファーは適切な値をそれらの入力構文de表示して、ユーザーはこれらをテキストとして編集できる。

以下は複合型でキーワード/値ペアーとして使用できるキーワードのテーブルです:

:tag tag

tagはユーザーとのコミュニケーションのために、その候補の名前として使用される。choice内に出現する型にたいして有用。

:match-alternatives criteria

criteriaは可能な値とのマッチに使用される。restricted-sexp内でのみ有用。

:args argument-list

型構築の引数としてargument-listの要素を使用する。たとえば(const :args (foo))(const foo)と等価である。明示的に:argsと記述する必要があるのは稀である。なぜなら最後のキーワード/値ペアーの後に続くものは何であれ、引数として認識されるからである。


Next: , Previous: , Up: Customization Types   [Contents][Index]