ドメインの基礎

date:2013/01/03
last modified:2013/01/09
author:渋川よしき

ドメインの持つ情報の粒度の大きさ、制約を把握しておくことで、ドメイン設計が正しく行えるようになるでしょう。基本的なプログラミング言語であれば、他の言語と似た構成にすれば特に迷うことはないとおもいますが、ゼロから考える場合には、「情報の正規化」が大切になります。

ドメインではいくつかの粒度の情報を組み合わせて、対象となるプログラムなどの情報を記述していきます。基本の構成要素となっているディレクティブは以下のような構成になっています。

.. ドメイン名:ディレクティブ名:: 必須引数[ オプション引数]
   :引数なしオプション: 説明
   :引数ありオプション 引数: 説明

   コンテンツ

ドメイン名

他のドメインと重複することなく、なるべく短い名前にします。Pythonの場合はpy、JavaScriptの場合はjs、Rubyの場合はrb、Erlangの場合はerlを使ってます。

ディレクティブ名

対象となる言語の、情報の基本単位です。Pythonであれば、モジュール、クラス、関数などが該当します。

ディレクティブが置かれた場所よりも後ろの行に対して「副作用」を与える実装を行うことができます。例えば、モジュールディレクティブが置かれた行の先に置かれているものは、すべてそのモジュールの構成要素であると、情報を付加させる、などです。クラスも同様です。

Sphinxではクラスディレクティブの後にメソッドのディレクティブをインデントして書くことが多いのですが、ObjectDescriptionを継承したクラスでは、before_content()after_content()がインデントの前後で呼ばれます。これらの中でネストされた情報をメモしていくことで、親子関係を記述することができます。

ディレクティブの引数

関数名、クラス名などがここに入ります。関数の場合は引数情報なども一緒にここに記述されます。対象となるものとなるべく近い表現が望ましいでしょう。ドメインの仕事の最初の山場はこの引数の解析です。引数付きの関数定義から、関数名を抜き出し、他のディレクティブの影響(モジュール名、クラス名など)を反映をさせて、完全修飾名を作り、Sphinxの内部データとして記録していきます。

ディレクティブ引数には「必須な引数の数」「オプションの引数の数」が指定できますが、ドメインの場合は必須の数=1として作られるケースが多いでしょう。

ディレクティブ名のところで、「ネストができない」と書きましたが、Pythonのようなモジュールの場合は、引数でルートからの階層情報も含めた名前を与えることによって解決しています。

.. py:module:: sphinx.domains.cpp

ディレクティブのオプション

結果は1行にまとまって、リスト化されるため、あまり長い情報を入れることはできません。タグ付け、フラグ的な情報の付加に限定されます。

引数ありオプションは、メソッドの引数(意味+型)を想定しています。sphinx.util.docfields.Fieldを継承して、独自なものを定義しない限りは、同じ引数を2つまでしか取れません。次のようなケースの場合はオプションは適しません。

  • 引数でまとめたい情報が3つ以上ある
  • 自由にたくさんの情報(複数行)を記述したい

上記のケースの場合は、ディレクティブにする必要があるでしょう。情報の粒度的に迷ったら、まずはオプションとして実装し、情報量が増加する見込みがついたらディレクティブとして独立させる方が良いでしょう。

また、あくまでも「オプション」なので、絶対に記述して欲しい項目があれば、ディレクティブの引数の方が良いでしょう。

コンテンツ

自由記述の項目です。文章を書くところです。コンテンツを受け取らないと設定することもできます。他のSphinx/Docutilsのディレクティブとは異なり、特殊な記法ではなく、通常のreStructuredTextを受け入れることが前提となっています。