2011年6月27日

エキスパート Python プログラミングの読書会 - 13

「エキスパート Python プログラミング」の読書会に行ってきました。 10章「プロジェクトのドキュメント作成」に関することで、この章は Web でも公開されています。

今回は、ざっくりと次の二点に関して話し合いました。

  • 業務でどうやってドキュメント (主に IT 業における技術文書) を書いてますか?
  • "Sphinx" (日本語) というツールの使い方、Tips の共有。

自分のメモによる時系列は、おおよそ次のようになります。

  • 参加者の自己紹介
  • 6/21 19:49 "ドキュメント作成は、開発者、ときにはマネージャもさぼってしまいがちな作業です。"プロジェクトのドキュメント作成 - http://t.co/pf2y18e #expertpython
  • 6/21 20:03 Q. 技術文章を書くためにどんな本を読んで勉強してる? A. ワインバーグ先生の本、日本語の作文技術、理科系の作文技術、エキPy(笑 #expertpython
  • 6/21 20:16 タイトルが明快になれば逸脱した話題はノイズに思えてくるので、情報のスコープが絞られる。後から振り返るときにどのような検索語句を使うだろうか?と問い直してみる。たいていの検索インデクスではタイトルの重みが強いことを利用する。 #expertpython
  • 6/21 20:18 レビューするときは見た目を変えてみる。内容を書き出すフェーズと、表示をリッチにするフェーズを分ける。「2つのステップで書く」ということ。 #expertpython
  • 6/21 20:30 Sphinx の autodoc を使うと docstring をドキュメントに反映しやすいので、doctest をやる気が上がるらしい。意図と実装が一緒になっているので、変更漏れが少なくなる。これもひとつの TDD。 #expertpython
  • 6/21 20:36 Sphinx の便利メモ。 / 逆引き辞典 - http://t.co/nRuJInz #expertpython
  • 6/21 20:45 ドキュメントの「ポートフォリオ」を作りましょう。再利用可能なテンプレートのことで、目的別に保管しておく。完成したドキュメントから作り直すと良さそう。先にポートフォリオを作り始めたら死亡フラグ。 #expertpython
  • 休憩
  • 6/21 21:24 "glossary" ディレクティブを使うと索引を生成できるけど、日本語だと Symbols にまとめられてしまう。日本語用パッチを作っている人もいるが、さらっとは取り込めない状態みたい。 #expertpython
  • 6/21 21:28 Python も一緒に入るみたい。 / Windowsへのインストール(スタンドアロンインストール) - http://t.co/rAU10zw #expertpython
  • 6/21 21:53 Sphinx の拡張レポジトリ。 / birkenfeld / sphinx-contrib - http://t.co/xatcvNQ #expertpython
  • 6/21 22:10 linkcheck で外部へのリンクも確認しましょう、ということをみんなで学んで終了。 #expertpython

これ以降では、後からつらっと思ったことも含めて書いておきます。

ドキュメントを書く

まずは「技術文書を書くための7つのルール」を確認しました。 誰に向けて何を書くか?という部分は文書一般に言えることだと思いますが、 自分が特になるほど〜と思ったのは次の3点です。

  • アイデアにフォーカスして、まずはレビューする。
  • 意味が分かり、動かせるサンプルを使う。
  • ドキュメント・ランドスケープを意識する。

作成とレビューのサイクル

PowerPoint や Word といった WYSIWYG (what you see is what you get: 作成中の文書と成果物が同じ見た目であること) ツールの場合、 とかく表示の調整から始めがちです。 ページ余白を調整してテーマや色遣いを決めて、フォントは何を使って装飾は... と、だいたい同じことに同じように時間をとられます。 過去のテンプレートを使い回しても、なんとなくアニメーションを追加してしまうかもしれませんね。 何かを書こう、と思ってツールを起動させても、その何かを書く前の準備が終わったら一休み、となりがちです。

一方で、メモ帳などのテキストエディタは文章に焦点を絞れるため、即座に何でも書き始められます。 とはいえ、読み直したときの抑揚のなさ、図を思い通りに配置することの難しさなどにより、そのままレビューするわけにもいきません。 また、無秩序に書き始めてしまうと、量が多くなったときにアウトラインを把握できなくなります。

これらの中間 (?) として、テキストエディタで書いて、何らかのツールを使って成果物を生成する方式があります。 数十年前には、書籍を出版するための適したツールがないから作っちゃおう、という著名な先生もいますが、 割と普遍的な課題ですから、現在までにたくさんの文法とツールが開発されています。

気軽に書き始められて、それなりの見た目 (目次が明快、強調部分が目立つ、図を取り込める、など) でレビューできて、 その結果を反映できる、というサイクルを回すためには reST や markdown、textile は良い選択肢だと思います。 少なくとも、独自フォーマットやローカルルールは控えた方が良さそうです。 日本語の場合はついつい中黒 (・) を使って箇条書きを表現しがちですが、 後からツールで処理する、つまり再利用性を高めるためには、"*" や "-" の方が良いかもしれませんね。

フィードバックのサイクルを繰り返す中では、変更履歴を追跡できるようにしておくことも重要です。 Word にも履歴管理機能はありますが、きちんと使えない人がいたり、使いすぎると動作がもっさりするなどの問題があります。 特に複数人が編集に関わる場合には、文書自体と履歴管理は分離しておいた方が良いと思います。

履歴管理されているとレビュー範囲が明確になります。 また、"文書ファイル名-日付文字列.拡張子" というルールでファイル名を変更する必要もありませんので、 どれが最新版か分からなくなってしまう問題が低減します。 ファイル名を変更するルールの場合、"最新版-課題XXXについて.docx"、"最新版2-課題XXXについて.docx" となりかねませんから。

何はともあれ、「1回書いたらそれでオシマイ!」ではなく、ある程度の期間に渡って継続的に更新し続けることがポイントです。 主要な考えを書き出して、それを他の人に見てもらい、意見を反映させて、さらに考えを書き足していける状態を作ることが目標となります。 要するにソースコード管理と一緒ですね。

実際に動作するサンプル

何かの手順書を作成する場合、「ここは手元の環境に合わせて XXX の部分を書き換えてください」と書くことも多々あります。 それ自体は悪いことではないと思いますが、例示が悪いと誤解が生じやすくなってしまいます。

たとえば、Java のプロジェクトを Subversion からチェックアウトして Maven で Jetty を動かす場合、 次のサンプルでは意図が伝わらないかもしれません。

$ svn co {Subversion の URL} hoge
$ cd hoge
$ cd example
$ vi {設定ファイル.xml}
--- サーバ情報を書き換える ---
$ mvn jetty:run

この場合は、Subversion の trunk から引っ張ってくるのか、 branch の場合はどれかが分かりません。 また、設定ファイルがひとつなのか複数なのかも分かりませんし、何のサーバ情報をどのように変更するかも定かではありません。 コピペして動かせませんし、何より hoge って何?となります。

コマンドサンプルの前後に説明を書き連ねることもできますが、 それよりは、そのまま実行できるように工夫した方が良いでしょう。 もしかしたら設定ファイルの見直しから始めなければならないかもしれません。 しかし、それによって外部への依存性が明らかになりますので、中長期的な観点では、 無駄な作業にはならないと思います。

サンプルはソフトウェアを客観的に見直すきっかけにもなります。 必要だと思っていたパラメータが実は使われていなかった、 もしくは、設定したつもりだったのに内部での読み取り間違いで反映されていない、 というケースもあぶり出されます。

ドキュメント・ランドスケープ

「ドキュメント・ランドスケープ」という言葉を知りませんでしたが、 この言葉は翻訳者の方々が原著者に問い合わせて NOTE に記載したとのことです。

「あるべきものがあるべき場所に存在する」というようなことで、 家がビルの屋上にあったらオカシイよね、などを判別するために使います。

たとえば、手順書であれば事前条件や想定読者が実際の手順より前にあるべきです。 先ほどの例であれば、コマンドを実行する前に svn コマンドと mvn コマンドをインストールする、 あるいはインストールされているマシンを使う必要があります。 そもそも Maven って何?という読者も想定されるなら、別途説明があった方が親切でしょう。

これまで読んできたドキュメントを参考にすると、こういうことはこの辺りに書いてありそうだ、 と、読者側で違和感なく受け入れられる構成を考えていくことになります。 何らかのテンプレートを踏襲したり、過去のドキュメントからコピーしてくるなど、 いわゆるノウハウを活用する部分と言えます。 「ポートフォリオ」の蓄積とも言い換えられます。

Sphinx あれこれ

Sphinx はそれ自体が文法を持っているわけではなく、 reST をまとめるツールと言えます。 このため、reST と markdown は比較対象として妥当ですが、Sphinx と markdown の比較には違和感が発生します。 レイヤーが違うわけです。 markdown をまとめるツールとしては jekyll (jekyll 日本語説明) がありますので、比較するならこちらが適当でしょう。 jekyll で構築されたサイトとしては gitready があります。

reST が拡張可能な仕様なので、Sphinx を作ることができたとも言えます。 ディレクティブという命令体系を拡張できますので、 reST がそもそも持っているディレクティブに加えて、 Sphinx によるディレクティブ、あるいは自分独自のプラグインでディレクティブを記述できます。 あるツールに対するラッパーという意味では、ラインエディタ ex におけるスクリーンエディタ vi と似た関係となります。

Sphinx を使って HTML を生成するときには、テンプレートエンジンとして jinja2 (jinja2 日本語) が使われます。 jinja2 にはテンプレート継承の仕組みがありますから、既存のテンプレートを再利用しながら、 必要な部分だけを自前の HTML で上書きできます。 たとえば、ヘッダーやフッターを書き換えたり、メニューバーをカスタマイズできます。

出力形式 (ドキュメントビルダー) は複数種類ありますので、表現は HTML だけに止まりません。 PDF や Windows ヘルプ、JSON や pickle にも出力できます。 JSON だけをサーバサイドに保存して Ajax を利用したドキュメントビューアや、 Python アプリケーションにドキュメントを組み込むといったアイデアも実現できそうです。

その他に、Sphinx でのドキュメント生成時に、ドキュメント内部から外部を参照しているハイパーリンクを確認できます。 これには勉強会参加者一同が驚きましたが、 linkcheck ターゲットで実行できます。

$ make |grep linkcheck
  linkcheck  to check all external links for integrity

$ make linkcheck
sphinx-build -b linkcheck -d _build/doctrees   . _build/linkcheck
Making output directory...
Running Sphinx v1.0.7
loading pickled environment... done
building [linkcheck]: targets for 24 source files that are out of date
updating environment: 0 added, 0 changed, 0 removed
looking for now-outdated files... none found
preparing documents... done
writing output... [  4%] README
(line   5) http://krondo.com/blog/?page_id=1327 - working
(line   5) http://skitazaki.appspot.com/translation/twisted-intro-ja/ - broken: HTTP Error 404: Not Found
(line   5) http://twistedmatrix.com/documents/10.0.0/core/howto/index.html - working
(line  10) http://skitazaki.appspot.com/translation/twisted-intro-ja/ - broken: HTTP Error 404: Not Found
writing output... [  8%] index
(line  11) http://twistedmatrix.com/ - redirected to http://twistedmatrix.com/trac/
(line  43) https://github.com/skitazaki/twisted-intro-ja - working
writing output... [ 12%] p01
(line   8) http://twistedmatrix.com/ - redirected to http://twistedmatrix.com/trac/
(line   8) http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python - working
(line   8) http://twistedmatrix.com/pipermail/twisted-python/2009-May/019706.html - working
(line  16) http://twistedmatrix.com/trac/wiki/Documentation - working
(line  16) http://twistedmatrix.com/trac/browser - working
(line  61) http://en.wikipedia.org/wiki/Locality_of_reference - working

--- snip ---

build finished with problems.
make: *** [linkcheck] Error 1

$ ls _build/linkcheck/
output.txt

存在するものは working 、リダイレクトが発生するものは redirected 、リンク先が見つからないものは broken が表示されます。 ターミナルの設定にも依りますが、それぞれのメッセージは色付けされているかもしれません。 見やすくなっていると嬉しいですね。

最終的な結果は output.txt というファイルに書き出されます。 ドキュメントのソースコードが階層化されている場合には、出力も階層化されます。

終わりに

エキPy の読書会に行ってきました。 効率的なコードの書き方に関することはありませんでしたが、 ドキュメントを書くことについて再考できました。

個人的には、多くの日本人ソフトウェアエンジニアに対して、得意なことに関しては次の順序関係が成り立つと思っています。

[日本語] >> [業務で使用しているプログラミング言語] > [英語]

ソフトウェアにはバグがつきもの、という開き直りもあるかもしれませんが、 そもそもそういったソフトウェアの仕様を日本語で書き出してみると、きっと書けないと思います。 馴染みのある日本語で正確に記述できないことを理解に乏しいプログラミング言語で記述しなさい、といっても、 規模が大きくなればなるほど、多様な人たちが混ざれば混ざるほど、それは無理のような気がしてなりません。 (ひとりプロジェクトや、プログラミング言語への理解が日本語への理解と同程度の人たちの集まりは除く)

英語で書けば論旨が明快になるとの考えは一理ありそうですが、 実際問題として、そんなに英語で読み書き (あるいは会話) できる人は多くありません。 少ない語彙から捻り出した文章はあやふやな表現に終始しがちですので、 まずは日本語で概要を共有してから、なんらかのプログラミング言語で実装するのが良いんだろうな、と思います。

とはいえ、日本語そのものに対する理解ですら怪しいのは如何ともしがたい、という部分が最大の難関なんでしょうけどね。。。

コメントを投稿