出典

著者Brian W.Kernighan
P.J.Plauger
訳者木村泉
出版社共立出版

序論

  • 世のプログラマの間には赤鉛筆派が多すぎる。彼らのうちのあるものは文字通りの赤鉛筆派であって、計算機でやるべきことまで手作業でやろうとする。またあるものは比喩的な意味での赤鉛筆派である。彼らは、計算機を使うには使うのだが、使い方が無様で手作業でやったも同然、というような人々である。(p2)

1章 手はじめに

  • もっと大きなプログラムの場合には,まず擬似コードでプログラムを書き,次にそれを実際に計算機にかかるものができるまでだんだんに詳しくしていく、というやり方は価値が大きい。このようにすれば,計算機にかかる形のものを書くこと無しに高いレベルで設計を改定,改良していき,しかも計算機で実行可能なものから遠く離れること無しに進んでいくことができる.(p14)
  • 細部をできるだけ下位に押し込む,という設計原理を忠実に守って仕事をするなら,できた新しい道具は以前のものとの両立生を保つことになる.(P20)
  • プログラムのどんな小部分を書くときにも,境界でのテストについて考えておくという習慣をつけて欲しい.〜 その努力には十分な報酬がある.(p26)
  • 境界に目をつけた極限的なテストを少数用意することは,でたらめに選んだテストでじゅうたん爆撃をするより遙かに優る.(p30)
  • だが,それぞれの場合にどんな出力が出るはずであるかを,前もって知っていなければならないことは,テストというものの基本的な原則である.もし結果を前もって知らないのであれば,テストをしていることにはならない.実験しているに過ぎない.(p31)
  • 一つの解答は,ある桁より先では欄飛ばしは扱わない,とするものである.だが,眼倉めっぽうに入力は間違いないものと仮定してしまうようなプログラムを書くことは愚かである.(p33)
  • プログラムの一つの部分が他の部分の働きについて知っていることが少なければ少ないほど,それらの部分を変更することは容易になる.〜 最良のプログラムは,それぞれは簡単な仕事しかしないような,相互結合の緩い機能単位群に基づいて設計されるものだ.(p36)
if(col.gt MAXLINE) tabpos = YES
if(col.gt MAXLINE) tabpos = YES
のような重複した条件判定をしているところもある.FORTRANではこういうところは
tabpos = YES
if(col.gt MAXLINE) tabpos = YES
と書くのが常識である.(p40)
  • 良いプログラムを書くための最も有力な方法は,読みやすいプログラムを書こうと努力することである.経験によれば,読みやすさはプログラムの品質に関する最高無二の判定条件である.(P46)
  • プログラムの構造を注意深く作り出し,プログラムをシステムから切り離すことは,一貫した主題になるであろう.実際そうすることは,大きなプログラム,現実のシステムに立ち向かうための唯一の方法である.(p55)
  • ソフトウェアの生産性を高めるための一つの方法は,絶えず少しずつ違った同じようなものを作り直すようにせず,すでにできあがっているものに基づいて仕事を進める,ということである.(p55)
  • 良いプログラミングを学ぶための最も良い方法の一つは,現実的なプログラムを読み,それについて考え,[なぜこういう風に書いてあるのだろう.]とか,[こういう風に書いてみたらどうだろう]とか考えてみることである.(p55)

2章 種々のフィルタ

  • フィルタをすっきりさせるための,たいていの場合に通用する方法は,入力データの各構成要素を認識するための秩序正しいやり方を見つけ出して,その秩序をプログラムの実行の流れに反映させ,スイッチやフラグをいろいろ使わないでも済むようにすることである.(p58)
  • ループの終了条件は,whileやuntilの後に置くにせよ,breakを制御するifと組み合わせるにせよ,なるべく一つの論理式であらわそうと努力するべきである.(p59)
  • 誤りの処理は読みやすさとは矛盾する.その点について議論の余地はない.だが,誤りの処理無しでは住まない.最良の言語を使ってさえ,それはものごとの主要な流れをわかりにくくする.というのは誤りの処理そのものがプログラムに,本来の仕事を表す構造とは別の構造を持ち込むからである.だが,はじめから誤りの処理のことをよく考えて書いたプログラムは,誤りの処理を後から気がついてペタペタ貼り付けたようなプログラムと比べて信頼性が高く,また長生きするものである.(p78)
  • 引数がどんなものであろうとプログラムが筋の通った、予測できる挙動を取るように、と考えてのことである.奇妙な指定を与えられたときにも,何か道理にかなったことをすべきである.(p86)
  • その上われわれは,translitを,そもそも誤りの警告をあまり出さないように作ったのであった.異常な引数が与えられたときには,可能な限り何か筋の通った解釈を取り,それが不可能なら無害な解釈を選らんだ.汎用の道具を作る場合,これはよい設計方針である.そのようにしておかないと,はじめに気付かなかったために有用な応用を切り捨ててしまう恐れがある.また,このような方針を取ると,誤り検出のジャングルを作って混乱を起こすことも防止できる.(p91)
  • フィルタを使ってプログラムを分離し,整合させることを一度覚えると,新しいプログラムを書かずにすでに存在しているプログラムを組み合わせる,という考え方が,より自由にできるようになってくる..新しいソフトウェア群をはじめから作りたいという誘惑に負けなくなり,すでに存在している断片を組み合わせて仕事をするようになる.つまり,読者は道具のよりよい使い手になるのだ.(p104)

3章 ファイルの処理

  • それよりもプログラムが内部で使っている名称を利用者が覚えていなければならない,ということの方がいけない.(p114)
  • プログラムを実際に使う前にしなければならない下ごしらえが少なければ少ないほど,利用者はプログラムを道具として意識するようになるものだ.(p117)
  • プログラムには根拠のない制限をつけるべきではない。特にたくさんのようなことをやらせようとしすぎたためにそうなる、ということがないようにすべきだ。もし、〜したかったら、fcopyに一枚皮をかぶせるべきだ。(p124)
  • プログラムを書いてみると、この種の小さい「機能」を次から次へと付け加えたい、という強い誘惑を感ずるものである。だが、気をつけてほしい。それらの機能が統一的な形でうまくかみ合うのでない限り、とかく無関係な機能のごった煮ができやすい。もし、ごく簡単な応用に対してさえ、使い方を調べながら使わなければならないようになったら、それは機能をつけすぎた証拠である。(p129)
  • 我々が下す結論は、常にプログラムが実際にはどのように使われるかを考えに入れたものでなければならない。(p138)
  • しゃべりすぎるプログラムはじきうるさがられるようになるものである。(p154)
  • (エラー処理について)これほどまでに神経質にならないでもすむようなプログラムは多い。まずい使い方をされても破滅的な結果が生じないならば、それでよいわけである。だがarchiveのようなプログラムでは、新しいファイルが作られるだけではなく、ファイルが変更されるので、誤りの検査が特に重要である。(p158)
  • 実はプログラムの階層構造というものは、プログラムづらそのものと比べると、設計のごく初期から変わることのずっと少ないものである。従ってプログラムの階層図は、〜有用である。流れ図というものは、プログラムをオウム返しにするに過ぎないので、プログラムが変更されていくにつれてすぐ現状からずれていってしまうのである。(p159)

4章 整列

  • ついでながら実際にはこのプログラムをbubbleと名付けるのはよくない。sortとすべきだ。そのようにすればアルゴリズムを改良したときに利用者をあわてさせないですむ。(p167)
  • 整列プログラムは3つの部分にはっきりと分割できることが多い。
    1. 比較作業
    2. 交換作業
    3. 整列アルゴリズム
    • もしこれらの3つの部分がきれいに分割されていれば、ほかの部分に影響を与えることなしに、それらをここに改良することができる。(p169)
  • そしてプログラムの正しさに自信を持つためには、まずプログラムを理解することが必要なのだ。(p179)
  • 簡単であるべき仕事をするのにいちいち作業用ファイル群に神秘的なパラメータを指定させることほど、利用者にそっぽを向かれる原因になりやすいことはまずない。(p187)
  • いつもマニュアル片手に出なければ使えないようなソフトウェアはだめなソフトウェアである。(p196) -> CreateFile API
  • あまり早い時期に機能の結合をするのは間違いである。少なくとも初めのうちは、一つのプログラムにはただ一つの機能を持たせておくべきだ。〜教訓は何か?機能は組み合わせ方がわかるまではばらばらにしておけ、というのがそれである。(p197)
  • 一般的にいって、出来るだけ相互の結合のない構成要素から成っていることが望ましい。それには出発点においてはもっとも制限の強い作り方、(たとえばパイプラインによる)が選ばれたものと考えて設計をするとよい。実際にプログラムをどのように仕立てるかについての決断は、出来るだけ後に残すようにし、選択の余地をなるべく大きくしておくことが望ましい。(p202)

5章 文型の照合

  • もし100%の完全さを求めるつもりがないなら、どこかほどほどのところに線を引くことが出来るはずである。個々の応用について少々の欠点が残ることには目をつぶることによって、適用範囲をずっと広げることが出来るのだ。(p212)
  • 大規模なソフトウェア開発プロジェクトで、システムの各部分を組み合わせてみたら思うように動かなくなったために表面化した虫が、実は虫の大部分を占めていたという話はよくある。〜たいていの虫が結局のところ組み立ての最終段階で見つかるのだとすれば、その最上位の段階をまずテストするというのは自然なことというほかないように思われる。(p218)
  • 条件判定を順々にやっていく場合、複雑な場合についての判定ほど後でする、というのが普通である。(p229)
  • 常に我々の目標は、明瞭で、曖昧さがなく、かつ覚えやすい機能しようについてに沿って書くというところにあり、プログラムを行き当たりばったりに書いて、それを何とか我慢して使おうとする、というのは我々のねらいとは逆なのであった。例外を設けすぎ、その場限りの小細工をやり過ぎれば、プログラムはなかなかできあがらず、かつ使いにくいものとなる。(p232)
  • ありふれたことは、することが出来るだけでは不十分である。便利に出来るのでなければいけないのだ。(p237)
  • 大切なのは各段階においてどの程度の抽象化をすれば適当かを見分け、下位の細部が入り込んでこないようにすることである。(p238)

6章 文書編集

  • 利用者を利用者自身の誤りからどの程度守ってやるべきかの判断は難しいが、我々の経験によれば、一般にはお節介はしないのが一番賢明である。利用者は何事もわかっているのだと仮定し,禁止事項や警告はできるだけ少なくするのがよい。〜あそことここの違いは次の点に存ずる。archiveは(中略)どちらかといえば専門的な道具であって、普通の人が毎日使うものではない。だからarchiveは何をするにも慎重なのである。(p284)
  • 一般に初期設定や終了処理については、このように後から考えるとよいことが多い。というのは,初期設定や終了処理でどれだけのことをしなければならないかは,一通り定常状態のことがわかって初めてはっきりしてくるものだからである.(p325)
  • どんなプログラムであれ,文書エディタほどの大きさになったら,その設計なりプログラム本体なりについて正しい見通しを得ることは,ことに使ってみた経験なしには,難しいことである.(p330)

7章 文書整形

  • プログラムを小出しに作る,というやり方にはよい点が多い.ただし,ここで小出しに作るとは,まず何か役に立つ仕事をするものを最小限度作成し,次にその骨格に肉を一切れずつくっつけていく,というやり方をいう.(p343)
  • bp指令は負のページ番号も許すようになっているが,これは,そういうものをいつか誰かが使うだろうと思ったからではなく,そうしても害があるとは考えられないからである.勝手な制限をつけると,いつか誰かのじゃまをすることになるものだ.(p358)
  • spaceとputとはある程度似ているから,spaceをputを呼び出す形に直すことも不可能ではないであろう.こうすると出力が1カ所にまとまるという利益がある.その場合難しいのは〜(中略)それは外見上目立たないだけにもっともたちの悪い病理学的データ連結関係だといえる.プログラムに重複があるのは明らかなのだが,どうやらこのままにしておいた方がましである.(p359)
  • こうすると呼び出し側のプログラムが,呼ばれる側のプログラムの引数に関する制限条件を知っていなければならないことになるからである.これも一種の,隠された依存性であるといえる.長期にわたって保守していくことを考えるとこれは危険である.というのは,呼び出し側の保守をする人物は,遅かれ早かれこの制限条件を忘れてしまうと予想されるからである.(中略)もちろんこの種のことはやり過ぎてはいけないが,ここではそのための損はわずかなものであるからやっておく価値がある.(p371)

8章 マクロ処理

  • 大切なのは,よい設計から出発することである.よく書けたプログラムについてプログラム書きの規律をゆるめることは,まずく書けたプログラムについてプログラム書きの規律を強めるよりずっとやさしいのだ.(p396)
  • この,データ構造の内部表示については知らなければならないルーチンにしか知らせないようにする,という情報隠蔽の考えは,プログラム設計を適切に進めていく上できわめて重要である.(中略)各機能単位はブラックボックスを形作り,外界に対してはっきり定まったインターフェースだけを提示する.(p400)
  • なおもちろんこの「知らなければすまない」というのは,本当に知らなければすまないのでなければならない.気をつけて作れば内部構造を隠すことが可能なのに,利用者の方でデータについて「知らなければならない」ようなルーチンを作ってしまう.というのはあまりにもよくある話である.(p401)
  • プログラム作りの初期の段階では,しゃれた検索方式は引き合わない.逐次検索方式はどんな場合にも向くというようなものではないが,出発点としてはよい.プログラム作りもやさしいし,一発で動く可能性が高い.後でそこが障害になっているとわかったら,もっと速いアルゴリズムに変更すればよい.(p401)
  • たいていの場合プログラマは,プログラムのどの部分で時間が食われているかを本当にはっきりとは知らないものだ.だから「効率」のためになされる努力(とそのために犠牲になったわかりやすさ)は,ほとんど全部無駄に名手しまう.経験によればあまり早い時期に能率化をやり過ぎてしまわないための最良の方法は,日常的にプログラムの効率測定を行うことである.(p406)
  • 「すっきりとした,まあまあの,使えるものをまず作り,必要なら後で磨きをかけ」ようというのである.マクロプロセッサがまだ全体として動き出していないうちに,(中略)くよくよしても始まらない.実際には〜ほとんどありはしない.難しいことは,やさしいことがしっかりできるようになってから手をつけても遅くはない.(p408)

9章 Ratfor から Fortran への翻訳

  • linectは共通領域clineを通じて受け渡される.このデータ領域を使うルーチンはgettokとsynerrの二つだけであるが,にもかかわらずこれを共通領域においておかないわけにはいかない.そうでないとlinectが必要になったときに参照できるようにするため,ほとんどあらゆるルーチンにおいてそれを引数として持ち回らなければならないことになってしまう.これは隠れた接続関係がプログラム全体としての結合度を低めるのに役立っている例である.(p445)

エピローグ

  • プログラムというものは,最良のプログラムでさえ,吸収するのに時間がかかるものである.また,使ってみようとも手直しをしてみようともせずにプログラムの全容を理解する,などということは滅多とできるものではない.プログラムに関して学ぶべきことのうちには,プログラムをいじってみて,つまり読み,改訂し,読み直してみて,初めて身につくような要素がたくさんある.
  • いま,読み,改訂する,といったが,これが鍵である.どんな技術を使って書こうとも,さっと書き下ろしたプログラムが最初から完璧な芸術作品になっている,などということはあり得ない.(中略)大幅な改訂をするなどというと,高価で時間を食うぜいたく,という風にきこえるかもしれないが,プログラムがすっきりできていて各機能単位が小さいときには,そんなことはない.そのうえ,プログラムを読み,改訂するという訓練を積んでいくと,だんだんはじめからましなプログラムが書き下せるようになっていくものだ.当いうのは,何を使うとよく何を使うのはよくないか,よい書法,悪い書法とはどんなものであるかが,どんどんわかってくるからだ.
  • プログラムの書き換えをする目的は,ほとんどの場合プログラムを簡単化し,理解しやすくし,その複雑さを管理可能な範囲内に押さえ込む,というところにある.複雑さの管理はプログラミングの神髄である.
  • 低いレベルについていえば,われわれは制御構造を注意深く選び,それを注意深く使った.(中略)その結果として,プログラムは読みやすいものとなった.
  • 各機能単位は,高い内部結合度を有しており,従って独立の単位を形作るにふさわしい理由を持っていた.それは気ままに切り出してきた機能をごちゃごちゃと寄せ集めたようなものではなく,また他の機能単位の一部が迷いだしてきた,というようなものでもなかった.
  • われわれは,設計上の決断とデータ構造を隠して,それらについて知らないですむ構成要素に走らせないようにすることによって,プログラムを変更しやすくするように努めた.
  • またわれわれは,オペレーティングシステムとの界面のできるだけ多くを,少数の基本操作の中に押し込めるように注意した.その結果プログラムの大部分は特定の環境に依存しないですむことになった.
  • 高いレベルについていえば,われわれはプログラムを,互いに共存できるように作った.その結果,新しいプログラムを書く代わりに既存のプログラムを組み合わせることによって複雑な仕事を処理することができることとなった.
  • すなわち,こうすることによって,われわれは,理解しやすく,信頼性が高く,丈夫で,作成方針が大きく変わっても,機種が変わってさえあまり影響がないようなプログラムを書くことができるのである.各水準において適切な構造を保つことは,単に結構なことというだけではなしに,複雑な仕事をうまく制御していく上で成否に関わる問題なのだ.
  • 第1の指針は最も大切である.それは単純さを保とう,というものである.(中略)もちろん,全くの無技巧ではすまない.常識はやはり必要である.(中略)われわれは道具を作ろうとしているのだから,できたプログラムは他人が使うものだ,ということを明記し,自分の仕事を複雑化させてでも,彼らの負担を軽くしてやる必要がある.
  • 第2の指針は,段々に作れ,というものである.複雑な仕事は,管理しやすい小段階に分割して処理すべきである.まず中心的な,最も重要な部分に集中し,飾り物には目を奪われないように注意しなければならない.
  • 第3の指針は,面倒なことは他人にやらせろ,というものである.毎回新規まき直しではじめないで,自分または他人が前に作ったものを使って仕事をすべきだ.また何かものを作るときは,後で関連した仕事をするときまた使えるように,十分一般的に作っておくべきである.(中略)そしてもちろん,可能な限り仕事は機械にやらせるべきだ.それが道具作りの究極的な目的だからだ.

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

管理人/副管理人のみ編集できます