346 第9章 ド キュメント とド キュメント オブジェクト この章では,S の関数,クラス,および メソッド のためのオンライン ド キュメントの使い方と開発方法を示す.オンラインド キュメントを利用 するためのユーティリティには,"?"演算子とその他のより専門的なツー ルが含まれる.これらは,ド キュメント オブジェクト を読み込んだり生成 したりする.その初期段階には自己ド キュメント (self-documentation) が用いられる.プログラマは,他の S のオブジェクトと同様,ダンプ,編 集,およびソース化のサイクルを用いてド キュメントを編集することが できる.ド キュメントには,S オブジェクトと他の S オブジェクトにつ いての情報の両方が含まれ,情報自身の記述には,多くのウェブ 文書の 基本である SGML 言語が用いられる.ド キュメントを含めた S のプ ロ グラミングは,S オブジェクトを用いた S のプ ログラミングの組み合わ せであり,ダンプされた SGML ファイルを利用しての編集とプログラ ミングが加わったものである.この章では,主に S の側での扱いを述べ, 追加のツール,特に SGML の側のツールについては,本書のウェブサイ トでの解説に任せる. S は,言語の一部としてユーザにオンラインドキュメントを提供する.関数やそ の他のトピックについての情報は,ド キュメント オブジェクト (documentation object) の中に保存されており,それは,ド キュメント メタデータベースの中 に,データベースツールを呼び出すときの meta="help"に対応して,順に保 存されている.ユーザは,ド キュメントオブジェクトやそれらに含まれる表示 情報を見つける "?"演算子などのユーティリティを用いてオンラインドキュメ ントを見ることができる.9.1 節では,オンラインド キュメントを見る方法に ついて述べる.関数,クラス,および メソッドは,それらの初期のド キュメン 9.1 オンラインド キュメントの閲覧 347 トを自分自身から生成する自己ド キュメント 化 (self-documenting) の機能をも つ (9.2 節参照).プログラマは,既存のオブジェクトか自己ド キュメントを基 に,他の S オブジェクトの編集ツールと同様のツールを利用して,ド キュメン トオブジェクトをダンプし ,編集し,そして再ソース化することができる.ド キュメントオブジェクトは,標準のマークアップ言語 SGML でその構造がコ マンド (タグ ) に変換され,テキストファイルにダンプされる.9.3 節では,ド キュメントの編集について扱い,9.4 節では,クラスのド キュメントについて, 関数やメソッドと少しばかり違う点について考察する.そして,9.5 節は,直接 にそれらを操作するためのドキュメントオブジェクトとツールについて述べる. S におけるドキュメントオブジェクトの構造は,直接 SGML で書かれた構造 と相似形になる.結果として,S のプログラマは,対話的なドキュメントのため の道具を開発する幅広い可能性を手に入れることができる.HTML や XML に 基づくブラウザのような道具によって,S のドキュメントの本来の構造と,そし て実際には多くの S の構造自身に接近することができる.同時に,S のプログ ラミングパワーをド キュメントオブジェクトの内容を調査して再編成するため に適用することができる.簡単な例は,365 ページに示した関数である.この本 を書くときに,筆者らは,ちょうど ,ドキュメントの 2 つの視点,S と SGML の間の協調動作に関する研究を始めた.進行中の開発については,本書のウェ ブサイト http://cm.bell-labs.com/stat/Sbook を参考にしてほしい.以下の節では,S 自身からド キュメントを見ることを議 論する.そして,これがたった 1 つの非常に豊かなド キュメントプログラミン グ環境の様相であることを理解してほしい. 9.1 オンラインド キュメント の閲覧 S は,ドキュメントを見るために演算子 "?"をもっている.演算子に続きト ピックの名前を入力すると,S はそのトピックのド キュメントを表示する. > ?sum Title: Sums and Products Usage: 348 第 9 章 ド キュメントとド キュメントオブジェクト sum(..., na.rm=F) prod(..., na.rm=F) Arguments: ...: numeric or complex objects. Missing values (‘NA’s) are allowed, but will cause the value returned to be ‘NA’ unless ‘na.rm’ is ‘TRUE’. na.rm: a logical value, default ‘FALSE’. If ‘TRUE’, missing values are ignored. Value: the sum(product) of all the elements of all the arguments. If the total length of all the arguments is 0, ‘sum’ returns ‘0’ and ‘prod’ returns ‘1’. Examples: meanX = sum(x)/length(x) Key Words: math 引数なしで,この演算子"?"自身を式として入力すると,"?"の詳細が表示さ れる. トピックが名前でない場合は,それを引用符で囲む必要がある.たとえば , "+"に関するオンラインドキュメントを見たい場合は, ?"+" とする.添え字や要素演算子は,左単括弧または左二重括弧 ?"[" ?"[[" で表される. すべての S 関数はオンラインド キュメントをもっている.もし ,その関数に 対して特別のドキュメントが何も記述されていなければ,ド キュメントは自動 的に生成される.これは,単に引数とそれらのデフォルト値を与えるだけであ るが,何もないよりかはよい.もし関数の作者が関数定義の最初にいくつかの コメントを含めておくと,その関数はより明示的な自己ド キュメントになり得 る ( 351 ページ参照).もしある関数が異なるクラスの引数に対するメソッド を もっていれば,これらのメソッド は,別々のオンラインド キュメントをもつこ 9.1 オンラインド キュメントの閲覧 349 とができる.これらは,メソッド の定義から自己生成させるものでもある.ま た,S のクラスは,クラスの定義から自動的に推論されるド キュメントを含む オンラインド キュメントももっている. ド キュメントの対象となるトピックは,特定の関数,メソッド,クラスのど れにも対応していなくてよい. ?Syntax とすると,S の構文のオンラインドキュメントを表示する.existsDoc(topic) を呼ぶと,トピックに対する明示的なド キュメントが存在しているかど うかを 確認できる.ただし,9.2 節で述べるように,自己ドキュメントはこの呼び出し によっては表示されない. "?"演算子は,さらに特殊なフォームで使うことができる.もし ,引数がこ の演算子よりも前にあれば,対象のド キュメントの型に関する解説の表示を要 求することができる. class ? file は,同名の関数とは全く異なり,クラス file 上のド キュメントのみを要求す るのである.ドキュメントの型として組み込まれているのは,"function"(こ れが標準の型である),"class" ,"method"である. クラスのドキュメントは特別に保存されているので,関数とクラスは同じ名 前をもつことができると同時に,異なるオンラインヘルプをもつこともできる. たとえば,?matrix は matrix 関数のド キュメントを表示するが, class ? matrix は,オブジェクトの matrix クラスについてのド キュメントを表示する. 同様に,ある特定の関数に対するメソッド のド キュメントを得るには,たと えば,次のようにする. method ? whatis これは,ユーザにどんなメソッド が関数 whatis に定義されているかを示し , そしてド キュメントの表示が要求されているその特定のメソッド をユーザに示 すための対話をスタートさせるものである.メソッド のド キュメントの表示を もう少し拡張するために,関数名と引数あるいはそれらのクラスとして付与さ 350 第 9 章 ド キュメントとド キュメントオブジェクト れるオブジェクトの両方を明示することができる.クラス matrix のオブジェ クトに対してその whatis が使うメソッド に関するド キュメントを見るには, method ? whatis("matrix") とする.また,クラスの名前でなくオブジェクトを渡すこともできる. method ? whatis(xm) とすると,これは,引数 xm に対して whatis が選択するメソッド なら何に対 してもメソッド のドキュメントを作り出す.もし ,xm がクラス "matirx"をも てば,上の例と同じ結果になる.しかし ,もしその引数の評価が単独の文字列 なら,"?"はそれをクラスの名前として解釈する. これらは,与えられたクラスに対して明示的に定義されたメソッド である必 要はない.S は,計算のメソッド を選ぶときに使われるルールを適用する.た とえば,もし whatis に対して matrix メソッドではなく array メソッドがあ る場合,クラス matrix が array を拡張するので,array メソッド のためのド キュメントが使われることになる. 9.2 自己ド キュメント 新しい関数,クラス,および メソッド について解説することは,非常に望ま しいことであるが,同時にその作成作業はいくぶんめんど うなことでもある. そこで,作業を簡単にしたり,作者がそれに取りかかるまでの代行をするため に,これらはすべて自己ド キュメントをもつ. ある関数のド キュメントを要求したが,どこにも明示的なものが作成されて いなければ,S は,次の 4 つのことを含んで,関数オブジェクト自身からドキュ メントオブジェクトを作り出す. 1. 呼び出しシーケンス 2. デフォルト値をもつ個々の引数 3. オプションとしての Description 段落.これは,ソースファイル上の関 数定義のすぐ 前にある数行のコメント行から作られる. 4. その他の重要なド キュメントセクションのためのスタブ ド キュメントが簡潔な形式でオンライン表示されるときには,ほとんどのスタ 9.2 自己ド キュメント 351 ブは省略される.3 番目の項目は,より重要な解説は後回しにして,関数の大 まかな解説を与えるために使われる最初のコメントのことを意味する. 例として,第 1 引数を第 2 引数の範囲に対して再尺度化する関数 reScale を見てみよう.関数のバージョンは 6.1.1 節の 216 ページで述べたものである. ここではもう少し洗練したバージョンを示そう.すなわち,引数 xrange で欠 損値があればそれを無視し ,2 つの便利な S 関数,range と diff を使うよう に改訂したものである. "reScale" = # the data in x, rescaled to the range of xrange. # # Missing values in xrange are ignored function(x, xrange) { xr = range(x, na.rm=T) yr = range(xrange, na.rm=T) x = (x - xr[1])/diff(xr) yr[1] + x * diff(yr) } コメントを記述する一番よい位置は,トップの行の付値演算子と関数定義の間 である.開始位置は他のところでもよいが,以後そこが開始位置として固定さ れるので,コメントの本文をあちらこちらに置くことはできない.reScale の オンラインド キュメントを表示するよう要求をすると,その明示的な解説がな い場合,自己ドキュメントオブジェクトが作成され,その有用な部分が表示さ れる. > ?reScale Title: Function reScale Usage: reScale(x, xrange) Arguments: x: argument, no default. xrange: argument, no default. Description: the data in x, rescaled to the range of xrange. 352 第 9 章 ド キュメントとド キュメントオブジェクト Missing values in xrange are ignored 最初のコメント行が抽出され,ド キュメントの Description セクションとし て表記されているのに注意してほしい.Description セクションへは,その関 数定義のコメント行のテキストが出力されており,記述中の段落を分けるため の空のコメント行も保持されているのがわかろう. タイプ入力を節約するための約束事として,S のオブジェクトか演算式を参 照するテキストを,‘x’ のように ‘と ’ で囲むことによって強調できる.これ は,このようなテキストを目立たせる簡単な方法であって,ド キュメントを読 みやすくする.ドキュメントを編集することになった場合,S は,このような テキストを適当な「コンピュータ出力」形式で表示する SGML タグに変換す る.ド キュメントが単純表示されるときは (それはデフォルトで "?"が生成す るものであるが ),そのテキストは再び引用符で囲まれて出力される.オフライ ン出力やブラウザによる表示のような他の形式での出力においてもそのテキス トは適切に強調されよう.このスタイルに従って,先の例におけるコメントを 次のように改訂するとよい. "reScale" = # the data in ‘x’, rescaled to the range of ‘xrange’. # # missing values in ‘xrange’ are ignored .... もう少し作業することをいとわなければ,S の引数や別の S 関数への参照とし て,あるいは別のタイプの参照として,そのテキストを識別するタグも存在す る.このようなタグを使うとド キュメントをブラウザ表示に向いたものにする ことができる.詳細については本書のウェブサイトを見てほしい. 関数のコメントは普通その関数を編集することから形成されるが,それらを 明示的に抽出したり置き換えたりするには functionComments を呼ぶとよい. > functionComments(reScale) [l] "the data in ‘x’," [2] "rescaled to the range of ‘xrange’." [3] "" [4] "Missing values in ‘xrange’ are ignored" 9.2 自己ド キュメント 353 すなわち,付値の左側にあるfunctionComments は,付値の右側が指すコメン トを 1 文字列につき 1 コメント行に変換するという置き換え関数の働きをする. その関数のための実際のド キュメントオブジェクトを作り出す用意ができてい れば ,dumpDoc を呼ぶと自己ド キュメント情報を含むファイルを生成できる. このファイルを編集して,より多くの情報を含んだドキュメントを作り出すと よい.そして,関数 sourceDoc によって,そのファイルを読み込んでドキュメ ントオブジェクトを生成する.ドキュメントの編集についての詳細は 9.3 節を 見よ. メソッド の自己ドキュメントについても,基本的に同じ方法をとる.この場 合,特定のメソッドに対する関数定義内の関数のコメントがそのド キュメント の記述を作り出す.dumpMethod を呼んで,319 ページで述べられた関数 show とクラス track に対するメソッド をダンプするとしよう.すると,次のように 関数定義にいくつかのコメント行を加えることができる. setMethod("show", "track", # this method turns the object into a 1-row matrix of # the values, with columns labelled by the positions. function(object) { vals = matrix(object@y, nrow = 1) dimnames(vals) = list("y:", object@x) cat("An object of class \"", class(object), "\"\n", sep = "", file = stdout()) show(vals) }) こうすると,最初のコメントは Description セクションへ現れ,シグニチャ は別のセクションに表示される. > methods?show("track") Title: Method show Usage: show(object) Arguments: object: argument, no default. 354 第 9 章 ド キュメントとド キュメントオブジェクト Signature: object: "connection" Description: this method turns the object into a 1-row matrix of the values, with columns labeled by the positions. 9.3 ド キュメント の編集 かなりの数のトピックに関して現在あるドキュメントは,dumpDoc(topics, file) によってテキストファイルにダンプすることができる.ここで,topics はトピックのベクトルで,file は適当なファイルか書き込み可能な S コネク ション (10 章参照) である.トピックは,事前に文書化しておく必要はない.も しそこに 9.2 節で述べた自己ド キュメントがあれば,それがド キュメントがダ ンプされたときの最初の内容を示すことになる.そのファイルがド キュメント として十分に編集されたならば, sourceDoc(file) とすれば,そのファイルが読み込まれてファイルの内容がドキュメントオブジェ クトに変換される. そのプログラミングのサイクルは,関数,クラス,メソッドによるプログラミ ングに適用されるダンプ –編集–ソース化のスタイルと同様である.主な違いは, 記述されたファイルは自分自身では S 演算式を構成するのではなく,SGML 言 語で記述されるということである.したがって,マークアップ言語で書かれた そのファイルを S のドキュメントオブジェクトへ翻訳するためには,ソースコ マンド を明示しなければならない. たとえば,351 ページの関数 reScale の自己ドキュメントをダンプするとし よう. > dumpDoc("reScale") [1] "reScale.Sgml" デフォルトでは,ファイル名は関数名に拡張子 .Sgml を付けたものとなる.し かし,dumpDoc の第 2 引数としてファイル名か適当な S コネクションオブジェ クトを与えることもできる. 9.3 ド キュメントの編集 355 そのファイルには,SGML マークアップ 言語で記述された特別のテキスト や追加されたドキュメントのすべてのテキストが含まれる.特別のテキストは SGML のタグの構文に従うものである.たとえば,タグは角括弧 ("<"と ">") で囲まれ,場合によってはその中に属性 (attributes)(S の名前付き引数に似て いる) ももつ.これに任意のテキストが続き,セクションは通常スラッシュを付 けた同一のタグで閉じられる.この中には追加のタグを入れ子で含むこともで きる.したがって,たとえば,タグ s-section は <s-section name="Note"> で始まり,テキストがこれに続き, </s-section> で閉じられる.SGML や関連するトピックに関する本およびオンラインドキュ メントには膨大な数がある.たとえば,その定義に関する「公式」ウェブサイ サイトは http://www.w3.org である.しかし,S のドキュメントを編集するために SGML について多くを知 る必要はない.自己ド キュメントから生成されるファイルの例に従うだけで十 分である. あえてそうする必要がない限り,dumpDoc によって生成されたセクションの いくつかを自分自身で編集すべきでない .たとえば ,使い方 (Usage:) のセク ションは,特別のコード を用いて S 演算式から作られている.すなわち,その 演算式のほとんど すべての部分に特化したタグが生成され,用いられている. これらのタグは,対話的なドキュメントツールを開発するために有用であるが, ダンプされたセクションは,読みにくく,ミスなしに編集することはさらに困 難を要するであろう.たとえば,reScale に対する Usage セクションは, Usage: rescale(x, xrange) のように表示されるが,その SGML は,次のようになっている. <s-usage> <s-call> 356 第 9 章 ド キュメントとド キュメントオブジェクト <s-function-name name="reScale"> reScale </s-function-name> <s-argument name="x"> </s-argument> <s-argument name="xrange"> </s-argument> </s-call> </s-usage> S の呼び出しの構造は SGML の構造に対応付けされている.これは有益である が,人が独力で編集するには不向きである.このようなド キュメントセクショ ンの編集が必要なときは,S のドキュメントオブジェクトを編集するとよい.た とえば,別の関数 reScale2 のドキュメントを同じドキュメントオブジェクト の中に合併することを考えよう.次の例はこれを行う 1 つの方法である. setDocSection("reScale", "s-usage", expression(reScale(x, xrange), reScale2(x, y, xrange))) setDocSection 関数は,expression の引数を最適な SGML フォームに変換 し ,それをこのド キュメントに対するメタデータオブジェクトに挿入する. こうすると,ダンプされたド キュメントファイルを人が編集することは,引 数の記述や返値の記述などのような通常のテキスト部分に限ることができるの である.ファイルを編集した後,この場合,sourceDoc("reScale.Sgml") に よって,改訂したド キュメントオブジェクトを反映することができる.S のド キュメントオブジェクトに関してタグが再解釈され,解釈されたオブジェクト はユーザのチャプタの meta="help" の部分に付値される.クラスとメソッド に関しては,メタデータオブジェクト上で直接作業するのではなく,ツールを 使ってド キュメントオブジェクトを取得したり設定したりすべきである. ドキュメントファイルは,ドキュメントを表示するセクション (Title ,Usage など ) に対応して,トップレベルのセクションに組織される.これらは,それぞ れ対応するタグ,s-title ,s-usage などにより記述される.各セクションは, SGML スタイルで記述された対応するタグによって境界分けされる.たとえば, タイトルセクションは "<s-title>"で始まり,"</s-title>"で終わる. もし尋ねられた名前に対するド キュメントオブジェクトがなければ,自己ド キュメントからダンプファイルが生成される.通常の出力でなされるように, いくつかのセクションを削除するよりは,著者によって書き換えができるよう に空のセクションをスタブとして残しておく.ファイル "reScale.Sgml" の一 9.3 ド キュメントの編集 357 部を示そう. <!doctype s-function-doc system "s-function-doc.dtd") <s-function-doc) <s-topics> <s-topic> reScale </s-topic> </s-topics> <s-title> Function reScale </s-title> <s-description> the data in x, rescaled to the range of xrange. <p> Missing values in xrange are ignored </p> </s-description) <s-usage) ...... </s-usage> <s-args> <s-arg name="x"> argument, no default. </s-arg> .... </s-args> <s-value> <!--Put description of return value in this section --> </s-value> .... <s-docclass> function </s-docclass> </a-function-doc> SGML におけるコメント — "<!"で始まるタグ —は,編集に対して情報を与え るセクションを示す.少なくとも,この SGML ファイル内の 2,3 のセクショ ンだけは,直接手作業で編集すべき,あるいはしなければならない.それらは, 主として次のものである. 358 第 9 章 ド キュメントとド キュメントオブジェクト s-title: そのド キュメント全体を表すタイトル s-arg: 各引数を記述する個別のセクション s-value: 関数により返される値を記述するセクション s-example: 関数の使用例を含むセクション 前に述べたように,ファイルのいくつかのセクション (たとえば ,s-usage) は,入れ子のタグの集まりになる.通常そのセクションは編集する必要のない ところである.しかし ,S における情報を抽出したり置き換えたりするために setDocSection 関数のような S のツールを使うことができる. s-args セクションの中では,個々の引数はそれぞれ,引数名を与える name=属 性 (属性は SGML 言語の専門用語) をもった s-arg タグで囲まれるサブセク ションをもつ.SGML では,通常通り,name=引数に与えられる属性文字列は, タグ名を囲む角括弧の内側に記述する.この文字列は,S 関数の特定の引数に 対するド キュメントを抽出するための S のツールによって使用される.それ は,SGML の構文において,ド キュメントオブジェクトの中の 1 つの要素の 名前を表現する方法としてとらえると最も良い.その要素自身は,この特別の s-arg の開始タグと終了タグの間にあるテキストである.たとえば,引数 x を "numeric vector"であると記述するテキストがほしければ,それに対応する SGML 構文は, <s-arg name="x"> numeric vector </s-arg> となる.s-arg タグ内のテキストはフリーフォーマットである.すなわち,こ のセクションにテキストを表示するとき,思い通りに語句を配置したり行を埋 めたりすることができる.もし 引数名が自己ド キュメントによって作り出され たものなら,その SGML の構文は自動的に生成されたものとなる.編集する のは通常のテキストのみということである. s-examples セクションでは,S 演算式の例が 1 つ以上の s-example タグ で囲まれる.s-examples タグは,テキストを記述するのではなく,S 演算式 の表示例を配列するものである.s-example タグはドキュメントの他の部分か らで際立たせて S 演算式を表示する.適当な対話的インタフェースやブラウザ を用いれば,これらのセクション内容を S のプロセスに渡して試してみること もできる. 9.3 ド キュメントの編集 359 ファイルの編集においては,スタブを実際の情報に置き換えたり,不適切な セクションを削除したり,また,description セクションの一部を他の適切な セクションへ移動したり,description を削除したりする.ファイルの開始と 終了を表す特別のタグは,自動的に生成されるものであり,ファイルを正しく 処理する重要なものである.これらは編集してはいけない. 先のファイルの編集されたバージョンは次のようになる. <!doctype s-function-doc system "s-function-doc.dtd"> <s-function-doc> .... <s-title> Rescale A Vector </s-title> .... <s-args> <s-argument name="x") numeric vector </s-argument> <s-argument name="xrange"> desired range, or arbitrary other numeric vector. Missing values are ignored in computing the range. </s-argument> </s-args> <s-value> the data in <code>x</code>, rescaled to the range of <code>xrange</code>. </s-value> <s-examples> <s-example> plot(x0, y0) gridLines = range(stdGridLines, y0) abline(h = gridines) </s-example> </s-examples> <s-see> <s-function-ref>pretty</s-function-ref> for choosing grid-line positions. </s-see> .... 360 第 9 章 ド キュメントとド キュメントオブジェクト <s-docClass> function </s-docClass> </s-function-doc> s-see セクション (これは "See Also"セクションとして表示される) の中の記 述には,特別のタグ s-function-ref を使う。これは,その題材をブラウザ やその他のドキュメントツールに S 関数を参照するものとして特別扱いさせる ためのものである.このような特別のタグの詳細はウェブサイトの解説を参照 せよ. s-topics セクションでは,s-topic タグによって,それぞれのテキストが その解説を識別する名前としてみなされるようになる.たとえば,次の形のセ クションを付け加えるとしよう. <s-topic>Grid Rescaling</s-topic> すると,ユーザは,このトピックの (完全な) テキストを参照することにより, 以前にアクセスしたトピック reScale と同じド キュメントにアクセスできる ようになる.たとえば, help("Grid Rescaling") とすると,?reScale と同じド キュメントを生成する.exp,log,logb のよ うなお互い関連し合う関数のド キュメントを作りたいとき,複数のトピックの 共通利用が必要になる.この場合,それぞれのド キュメントは,3 つのトピッ クをもっていて,そのどれからもアクセスが可能である. ド キュメントファイルの他のタグはド キュメントオブジェクトを処理する ときに自動的に生成される.たとえば,s-docClass タグは,文書全体が含む ド キュメントの種類を定義する.method と class のド キュメントに対し て は,特別のドキュメントクラスがある.一般的な目的の場合,ドキュメントは, "function"と等しい docClass をもつ.ド キュメントオブジェクトを管理す る S 関数は,あるド キュメントを特別に扱うために,ド キュメントクラスを使 うことができる.たとえば,method のドキュメントには,そのメソッド のシグ ニチャについての情報を記述する s-signature セクションが含まれる. ファイルを編集し終えたら,sourceDoc を呼ぶことにより,そのドキュメン トを S のソースとして反映させることができる.ファイルにつけれらた拡張子 ".Sgml"は省略できる.すなわち,sourceDoc 関数は,異なる拡張子をもって 9.3 ド キュメントの編集 361 いる複数のファイルに対しても作用し,要求通りにファイル名を形成する.先の 例では,変更されたド キュメントオブジェクトを生成するには次のようにする. > sourceDoc("reScale") [1] "reScale" "Grid Rescaling" sourceDoc により返される値は,このファイルに関係があるすべてのド キュメ ントトピックのベクトルである.sourceDoc の本質的な副作用は,S チャプタ 内のドキュメントに関連するメタデータベース内にドキュメントオブジェクト を保存することである.デフォルトでは作業データ内である.普通,関数かク ラスの定義が記述されているのと同じチャプタ内にドキュメントが必要となろ う.そのチャプタを明示するために,sourceDoc に対して引数 where=を使う ことができる. 以下に示す reScale に対するオンラインド キュメントは,これまでの変更 が反映されている. > ?reScale Title: Rescale A Vector Usage: reScale(x, xrange) Arguments: x: numeric vector xrange: desired range, or arbitrary other numeric vector. Missing values in ‘xrange’ are ignored. Value: the data in ‘x’, rescaled to the range of ‘xrange’. Examples: plot(x0, y0) gridLines = range(stdGridLines, y0) abline(h = gridines) See Also: ‘pretty’ for choosing grid-line positions. メソッド のド キュメントは,同じ dumpDoc 関数を拡張することによってダ ンプされ,編集される.メソッドドキュメントを編集したいということを示す 362 第 9 章 ド キュメントとド キュメントオブジェクト ためには,引数に special="method" を含める.このとき,引数 sig=によっ てそのメソッドに対するシグニチャを与えることができる. 関数 whatis とシグニチャ "vector"のド キュメントをダンプするためには 次のようにする. > dumpDoc("whatis", special="methods", sig="vector") [l] "whatis.vector.Sgml" このファイルを,前と同様,編集し,ドキュメントとして反映させればよい.そ こには,そのド キュメントクラスを示す "method"と s-signature タグを含 むので,sourceDoc は,このファイルをメソッドドキュメントのソースとして 適切に反映させる. 9.4 クラスのド キュメント 化 2,3 の細かいことは別にして,クラスのドキュメントは,関数ドキュメント と同様よく取り扱われる.クラスは,その構造表現から作り出される自己ドキュ メントをもっている.クラスのド キュメントにコメントを加えるための便利な 短絡的手段は今のところない. クラスのド キュメントをダンプするためには,dumpDoc 関数に引数として special= "class"を含めればよい.クラスのドキュメントは異なったタグ (た とえば,s-args ではなく s-slots) をもっており,s-docClass は,"class"で ある. 編集されたドキュメントは,sourceDoc によってソース化される.これには, どんな special 引数も必要としない.すなわち,s-docClass によって,どん なド キュメントオブジェクトが生成されるかが決定される.クラスのド キュメ ントの構造を見るためには,たとえば sgmlTag のような標準的なクラスのド キュメントを 1 つダンプしてみればよい. 9.5 ド キュメント オブジェクト S のドキュメントを編集するには,ファイルへド キュメントをダンプし,その ファイルを編集し ,そして,そのファイルをソース化して対応するド キュメン 9.5 ド キュメントオブジェクト 363 トオブジェクトを生成するか再生成する.すると,このオブジェクトは,選ば れているデータベースの "help" メタデータ内に保存される.そのド キュメン トオブジェクトは,オンラインド キュメントを出力したりダンプするためのす べてのツールによって使用される.通常の編集にとって,これらのオブジェク トを直接付値することは望まれることではない.たとえば,ド キュメントユー ティリティはトピック間の整合性を維持するが,直接の付値はそれを乱す危険 があるからである. ドキュメントオブジェクトはトピックに対応する.ほとんどの場合,1 つのオ ブジェクトに 1 つのトピックがあるだけであるが,先の例に示したように,い くつかのトピックが一緒に文書化されることもある.ド キュメントユーティリ ティは,対象のドキュメントオブジェクトを「別名付け (aliasing) 」することに より,これを管理している.トピックを付け加えるとき,対象のドキュメントオ ブジェクトをダンプして編集することによって,別名を削除するか導入すると よい.ドキュメントユーティリティは,そのドキュメント内の別名についての情 報を管理する.その情報は sourceDoc が呼ばれると更新される.1 つの例外と して,別名をもったトピックを削除するとき,短絡的手段として,removeDoc に引数 all=F を与えれば,トピックのいくつかだけを削除できる. トピックの 1 つを引数として指定して getDocTopics を呼ぶと,別名付けら れたトピックをすべて一覧表示することができる. > getDocTopics("sin") [l] "cos" "sin" "tan" データベース上に保存されているド キュメントオブジェクトの一部を変更す るには,setDocSection 関数を呼べばよい.他の情報 (たとえば,相互参照の 表) を構成したり,あるいは高度な操作のためには,オブジェクトに直接アク セスすることができる.以下に示すユーティリティはそれらを検討するのに役 立つ. 通常のオブジェクトに対する関数 get,exists ,find と非常によく似た働 きをする関数 getDoc ,existsDoc ,findDoc によって,ドキュメントオブジェ クトを直接操作できる.dumpDoc と sourceDoc を一緒に用いると,それらは, 関数の場合と同様のプログラミングサイクルとスタイルをサポートする.関数 removeDoc はドキュメントオブジェクトを削除する.クラスとメソッド のメタ 364 第 9 章 ド キュメントとド キュメントオブジェクト データオブジェクトに関しては,標準ツールのみを用いてドキュメントオブジェ クトを扱うことを強く推奨する.それらは,少し異なるものの,類似の関数は 他のオブジェクトに対して行うのとほぼ同じ動作をする. ド キュメントオブジェクトは,クラス "sgml"をもっている.オブジェクト のbody は,実際の情報のすべてを含む.この情報は,SGML タグとの類似性に 基づいて編成されている.正確には,sgmlTag オブジェクトのツリーとして編成 される.各 sgmlTag オブジェクトは,タグをもっている。それは,"s-title"の ように,SGML 内の対応するタグを明示する文字列である.各 sgmlTag オブ ジェクトはそれ自身の本体をもっており,それは普通リストである.リストの 要素は,通常のテキストか他の sgmlTag オブジェクトのいずれかである.関数 docTag と docBody は,そのタグ名と本体を抽出する. s-arg のようないくつかのタグには SGML の意味での属性が含まれる.そ れは,クラス named のオブジェクトとして S の中で自然に表現されるものであ る.標準的なドキュメントオブジェクトでは,SGML 属性は,ほとんどの場合, 引数やスロット名を与えるための限られた利用しかされない.しかし,sgmlTag クラスにおけるメカニズムは,将来の可能な拡張に対して,きわめて汎用的で ある.関数 docAttributes はその属性を抽出する.もしそのタグが SGML 属 性を使用しないときには長さがゼロとなる. sgmlTag クラスは,SGML で書かれた対象のド キュメントを完全なツリー 構造で表現するものである.結果として,S による計算で,ド キュメントの構 造の全体が利用可能になる.S におけるド キュメントオブジェクトに対する根 本的な設計目的は,そのオブジェクトを用いて S の内部で行う計算か,あるい はそれに対応する SGML ファイルを用いて S の外部で行う計算のいずれかを 可能とする全情報をプログラマにもたせることである. S の内部でド キュメントオブジェクトを操作する計算は,ツリーの中のすべ ての sgmlTag オブジェクトを用いる場合と用いない場合がある.S の 1 つのド キュメントのトップレベルのセクションを用いて動作するためには,ツリーの 最初のレベルのみ必要となろう.この目的に対して,9.3 節で述べた標準のタグ 名を利用して,セクションを抽出したり置き換えたりするために,docSection 関数を使うことができる.より一般的な計算は,たとえば,特定の用語やトピッ クへの参照を見つけるためには,ツリーの下のレベルでも動作する必要がある. 関数 rapply はこのような計算に役に立つ.すなわち,この関数はあるクラ 9.5 ド キュメントオブジェクト 365 スに対して計算を制限するフィルタを与えたり,スピード を上げるために C で 書かれた再帰的なツリー探索 (tree walk) を行ったりして,計算をツリー構造 のすべてのノードに再帰的に適用するのである.例として,"code"タグで囲ま れたユニークな文字列をすべて取り出す簡単な関数について見てみよう. "allCode" = ## all the material contained in ‘"<code>"’ tags ## in the documentation for ‘topic’, function(topic) { dac = getDoc(topic) codeText = function(obj) { if(identical(docTag(obj), "code")) unlist(docBody(obj) ) else NULL } text = rapply(docBody(doc), codeText, "sgmlTag") sort(unique(text)) } reScale のド キュメントにそれを適用すると,次のようになる. > allCode("reScale") [1] "x" "xrange" 同じ論理は,たとえば,既存の引数かド キュメントのトピックにテキストを一 致させる s-function-ref のように,多くの相互参照タグを操作するための より一般的な関数の中でも使うことができる.rapply は,また,S の内部のド キュメントオブジェクトの編集をより洗練することにより,ツリー構造のノー ド を置き換えるためにも使うことができる. allCode 関数は,その引数として,ド キュメントオブジェクトではなく,ト ピックをとる.それが意味をなすとき,トピックを扱うことは,ド キュメント オブジェクトをど う組織するかといった細かなことからユーザの計算を分離す る助けとなる.その原理は,クラスとメソッドによるプログラミングのそれに 類似している.これは,通常,ユーザレベルの計算からメタデータの明示的な オブジェクトを遠ざけることができるということである.
© Copyright 2024 Paperzz