5. サンプルコードの作成

良いサンプルコードが最良のドキュメントであることも少なくありません。全ての段落とリストが透き通る水のように明快だとしても、プログラマは良いサンプルコードを期待します。結局、文章とコードは異なる言語であり、読者が最後に望むのはコードです。そしてコードを文章だけで説明するのは、イタリア語の詩を英語で解説するようなものです。

良いサンプルコードは正確かつ簡潔であり、素早く理解でき、最低限の副作用を持ち、簡単に再利用できます。

正確なコード

サンプルコードは次の基準を満たすべきです:

サンプルコードはユーザーが書くコードに対して直接影響を及ぼせる機会です。そのため、サンプルコードにはあなたのプロダクトを一番上手く使う方法を示すべきです。もし一つのタスクを行う方法が複数あるなら、開発チームが一番良いと判断したやり方を載せてください。もしあなたのチームが複数あるアプローチの利点と欠点を考えたことがないなら、時間を取って考えてください。

サンプルコードは常にテストしてください。時が経ちシステムが変更されると、サンプルコードが動かなくなる可能性があります。サンプルコードを他のコードと同じようにテスト・保守する備えをしましょう。

ユニットテストをサンプルコードとして使うチームも多くありますが、それが悪い考えであることもあります。ユニットテストの主目的はテストですが、サンプルコードの唯一の目的は教育です。

サンプルプログラムを数行だけ抜き取ったものをスニペットと呼びます。スニペットは完全なサンプルプログラムほどには厳密にテストされない傾向にあるので、スニペットが多いドキュメントは時が経つにつれて劣化していくことが少なくありません。

サンプルコードの実行

良いドキュメントはサンプルコードの実行方法を説明します。例えば、ユーザーが何かを行うために必要なこととして次のような指示をドキュメントで与える必要があるかもしれません:

ユーザーがこういった操作を正しく行えるとは限りません。場合によっては、サンプルコードをドキュメントから直接実行・実験できることが望ましいでしょう(「ここをクリックでこのコードを実行」の機能です)。

ライターはサンプルコードを実行したときに期待される出力あるいは結果を説明する必要がないかを考えるべきです。特にサンプルコードを実行するのが難しいときは必要性が高まります。

正確なコード

サンプルコードは重要な要素だけを含んだ簡潔なコードであるべきです。初心者の C プログラマが malloc 関数の使い方を学んでいるなら、その人には数行のスニペットを示してください。Linux ソースツリーを丸ごと渡すべきではありません。関係ないコードは読者の集中を妨げ、困惑させるだけです。ただしそうは言っても、バッドプラクティスを使ってコードを短くすることは絶対にあってはいけません。必ず正しさを簡潔さに優先させてください。

理解できるコード

明快なサンプルコードを作るために、次の推奨事項に従ってください:

練習問題

サンプルプログラムとして最も適しているのは次のどれですか? 対象読者は go.so API に初めて触れるソフトウェアエンジニアだとします。

  1. MyLevel = go.so.Level(5, 28, 48)
  2. MyLevel = go.so.Level(rank=5, 28, 48)
  3. MyLevel = go.so.Level(rank=5, dimension=28, opacity=48)

最も適しているのは 3 です。サンプルコードを可能な限り短くしたい誘惑に駆られるかもしれませんが、パラメータを省略しては初心者が学びにくくなってしまいます。

コメントの付いたコード

サンプルコードのコメントでは次の推奨事項を意識してください:

コードの説明はコードの中でコメントとして行うべきでしょうか? それともコードの外で文章 (段落またはリスト) として行うべきでしょうか? ここで注目すべきは、読者がスニペットをコピーするとコードだけではなくコメントもコピーされる事実です。そのためペーストされたコードに含まれるべき説明は全てコードコメントとして含めてください。これに対して複雑な概念を長く説明するなら、サンプルコードの前に書くのが適しているでしょう。

注意: サンプルコードの短さと簡単さを優先してプロダクションで使えないコードを示さなければならないときは、その判断があったことをコメントに書いてください。

練習問題

次のスニペットのコメントには何か問題がありますか? このコードの対象読者は br API に初めて触れるプログラマで、ストリームという概念をある程度知っているとします。

/* Create a stream from the text file at pathname /tmp/myfile. */
/* (pathname (/tmp/myfile) にあるテキストファイルからストリームを作る。) */
mystream = br.openstream(pathname="/tmp/myfile", mode="z")

このコメントには次の問題があります:

  • コメントはコードのほとんど明らかな部分を説明しています。
  • コメントはコードの明らかでない部分を説明していません。具体的には、mode はどのようなパラメータで、"z" という値は何を意味するのですか?

再利用できるコード

読者がサンプルコードをより簡単に理解できるように提供すべきことは次の通りです:

簡単に理解できるサンプルコードがコンパイルできて簡潔なら、それは最初に見せるものとして申し分ありません。しかしそのコードが組み込み先の他のアプリを落とすなら、読者の顔を曇らせるでしょう。サンプルコードを書くときは、そのコードが他のプログラムに組み込まれたときに生じうる副作用に気を付けてください。セキュアでないコードやひどく遅いコードを欲しがる人はいません。

望ましい例と望ましくない例

読者に何をすべきかを示すのに加えて、何をすべきでないかも示した方がよい場合もあります。例えば多くのプログラミング言語では等号の両隣に空白を許していますが、bash のように等号の両隣に空白が許されない言語もあります。そういった言語のチュートリアルを書くときは、次のように望ましい例と望ましくない例の両方を示すと読者のためになるでしょう:

# A valid string assignment.
# (正しい文字列の代入)
s="The rain in Maine."
# An invalid string assignment because of the white space
# on either side of the equals sign.
# (等号の隣に空白があるので、これでは文字列を代入できない。)
s = "The rain in Maine."

一続きのコード

良いサンプルコードは様々な複雑さを持ったコードを示します。

学んでいる技術を全く知らない読者はまず最初に単純な例を渇望します。最初に示される最も基本的なサンプルコードはたいてい Hello world と呼ばれるプログラムです。基本をマスターしたら、エンジニアはもっと複雑なプログラムを欲しがります。良いサンプルコードは単純なコードからそれなりに複雑なコード、そして複雑なサンプルプログラムをバランスよく含むべきです。

練習問題

関数という概念を初学者に紹介するチュートリアルで使う関数として最も適しているのは次のうちどれですか?

  1. 次の四つの関数:
    1. パラメータを持たず、値を返さない関数
    2. パラメータを一つ持ち、値を返さない関数
    3. パラメータを一つ持ち、一つの値を返す関数
    4. パラメータを三つ持ち、一つの値を返す関数
  2. 次の一つの関数:
    1. パラメータを三つ持ち、一つの値を返す関数
  3. 次の二つの関数:
    1. パラメータを一つ持ち、一つの値を返す関数
    2. パラメータを三つ持ち、一つの値を返す関数

最も適しているのは 1 です。様々な複雑さを持つサンプルコードを提供するのが通常は最も賢明です ──初学者向けのドキュメントでは特にそうです。一番複雑なサンプルプログラムを一気に見せたくなる誘惑にどうか打ち勝って、初学者が渇望とする初級および中級レベルのサンプルプログラムを追加してください。

この次は?

おめでとうございます! あなたは『テクニカルライティング Two』の pre-class 部を完了しました。

あなたの機関で『テクニカルライティング Two』の in-class 部が利用可能なら、ぜひ受講してください。あなたが in-class 部を主催するのであれば、facilitator's guide を参照してください。

『テクニカルライティング One』で触れたトピックを 6. まとめ に簡単にまとめてあります。