̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ IT ニュース&コラム 2013/ 7/ 8 通巻627号 技術版 ソフトウェアデザイン館 Sage Plaisir 21  ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ goto 系をむやみに禁止するな - リーダブル・コード(5) 1980年代では、プログラミング言語 BASIC(Visual Basic ではない)が 主流でした。 BASIC 言語は構造化プログラミングが考慮されておらず、 処理の流れを追いにくいため、スパゲティ・プログラムと揶揄されました。 そして、スパゲティ・プログラムの原因である goto 文を使用禁止とする コーディング・ルールが生まれました。 goto 文を使う必要がなくなったのは、構造化プログラミングとオブジェクト 指向をプログラミング言語がサポートするようになったからです。 構造化プログラミングによって、分岐の条件を満たさなかったときの ジャンプ先と、繰り返しループの最後から最初に戻るときのジャンプ先が すぐに分かるようになりました。 ループにおいては、ループから抜ける break や、次の要素のループの先頭に戻る continue が、多くの プログラミング言語でサポートされました。 関数の残りの処理をしない return もサポートされました。 Visual Basic では、Exit ... という 命令になっています。 しかし、break, continue, return は、ジャンプをする命令であるため、 goto と同じく禁止すべきと主張をする者が現れました。 スパゲティ・ プログラムの原因がジャンプ命令にあると考えているのでしょう。 しかし、前述のように分岐と繰り返しにもジャンプがあるので、ジャンプ 自体は原因ではないのです。 ジャンプ先を探さなければならないことが 原因なのです。 ループにおいて、break, return, 多重ループを抜ける goto は、 残りの要素を処理しない分岐に相当し、cotinue は、現在の要素を処理 しない分岐に相当します。 ジャンプ先を探す問題がないことだけでなく、 早めに処理対象を減らす効果があります。 しかも、厳密に構造化 プログラミングに従うよりも処理が速く、ネストも浅くなります。 break, continue, 最後以外の return, goto を禁止すると、同じ流れを させるための工夫をすることになります。 その結果は「必ず」条件文が 増えることになり、かえって処理の流れを追いにくくなってしまうのです。 goto 系がある場合、 ある集合に対する要素のループ開始   if ( 条件を満たす最初の要素が見つかった )     見つかった要素 = 現在の要素     break; /* 以後の要素は処理しない */ ループ終了 goto 系がない場合、 ある集合に対する要素のループ開始   if ( まだ条件を満たす最初の要素が見つかっていない )     if ( 条件を満たす最初の要素が見つかった )       見つかった要素 = 現在の要素 ループ終了 オブジェクト指向をプログラミング言語がサポートするようになった のも、goto 文を使う必要がなくなったもう1つの重要な要因です。 問題が発生して処理が続行できなくなったときは、なるべく早く処理を 中断しなければ副作用が発生するリスクが高まります。 つまりエラーが 発生したら、処理を中断しなければならないのです。 しかし、処理を 中断するためには、処理で使用しているファイルや配列などをクローズ したり解放したりする必要があります。 ロックの解放やログアウトも 必要になるでしょう。 IT 以外なら、たとえばバーナーの火を止めなけ ればなりません。 これらを終了処理と言います。 中断する命令は、return, throw(C++言語), exit などがあります。 終了処理は、中断する命令を実行する前に実行しなければならないため、 すべての中断命令の前に終了処理を記述しなければなりません。 中断命令だけなら、まだマシなのですが、関数の中で中断が発生する こともあるので、すべての関数呼び出しに対してエラーチェックを行い、 終了処理もすべての関数呼び出しに対して記述しなければなりません。 これでは、プログラム・ソースが終了処理だらけになってしまい、 何をしているプログラムであるか分からなくなります。 そこで、goto, try〜finally(C++言語) を使って、終了処理にジャンプ させれば、終了処理を何度も書く必要がなくなります。 中断しない場合 でも終了処理は行われるので、関数の終わりの方の1か所にジャンプする コードを書くことになります。 オブジェクト指向をプログラミング言語がサポートするようになると、 オブジェクトが参照されなくなったときに自動的に呼び出される デストラクター(関数)が使えるようになります。 関数の中のローカル・ オブジェクトは、関数を抜けると参照されなくなるので、関数を抜けると 自動的にデストラクターが呼び出されます。 そこにオブジェクト自身の 終了処理を記述しておけば、オブジェクトを使う側は終了処理を記述 する必要がなくなり、終了処理にジャンプする必要がなくなるのです。 JavaScript はデストラクターが使えませんが、try 〜 finally を使えば、 終了処理にジャンプできるため、goto が言語仕様から無くても問題 ありません。 ちなみに、デストラクターが使えないことは不便ですが、 終了処理の順番を制御できるメリットがあります。 C言語は、デストラクターも finally も使えません。 だから、残りの 処理を行わない分岐に相当する中断や、エラーが発生したときに中断する ときに、終了処理にジャンプする goto が必要なのです。 ただし goto のジャンプ先は、関数の中で goto より後の1箇所に制限する必要があります。 そうしなければ、処理の流れがごちゃごちゃになり、スパゲティ・プログラム のできあがり、になります。 参考: リーダブルコード - より良いコードを書くためのシンプルで実践的なテクニック オライリージャパン ISBN-13: 978-4873115658 7.5章, 7.6章, 7.7章 スパゲティプログラム - BIGLOBE百科事典 http://jiten.biglobe.ne.jp/j/ea/da/c0/91ca6864c8ef56ac8402cc2e04d613d5.htm 構造化プログラミング - BIGLOBE百科事典 http://jiten.biglobe.ne.jp/j/2e/b0/d4/a55da70bfe5ef513bc29e3bd94bcd815.htm 注目ニュース 一覧 ◇ 米紙、PRISM に関する新たなスライドを公開。電子メールなどリアルタイムで監視か。 http://japan.cnet.com/news/business/35034066/ … フィルタリング技術を使って、条件に合うメールをすべて提供。 特にアメリカ以外。 ◇ アップル、透明になるベゼルの特許を取得。 http://japan.cnet.com/news/service/35034303/ … ゲームに使うなら、ベゼル(画面の端)は無くてもいい。 ◇ Android アプリの99%に乗っ取りの危険性。セキュリティ会社が警告。 http://japan.cnet.com/news/service/35034309/ … 信用されているアプリが改ざんされると大問題に。 ◇ Internet Explorer 11の新機能は、WebGL対応、内蔵開発ツール強化、パフォーマンスの向上など。 http://www.publickey1.jp/blog/13/internet_explorer_11webgl.html … IEもプロファイラー搭載へ。 ◇ IE11 でユーザエージェント文字列から MSIE が消えた件。 http://hyper-text.org/archives/2013/07/ie11_user_agent_string.shtml … Firefox と同じ機能になったため。 ◇ Windows Azure、モバイルサービスでiOSアプリを自動生成。Active Directory機能も追加。 http://www.publickey1.jp/blog/13/windows_azureiosactive_directorybuild_2013day2.html … iPhone でも Active Directory が使えるように。 ソフトウェアデザイン館 Sage Plaisir 21 ホームページ >>> http://www.sage-p.com/ メルマガ >>> http://www.mag2.com/m/0000083983.html ブログ >>> http://blog.livedoor.jp/sage_p/ ツイッター >>> http://twitter.com/Ts_Neko ダウンロード >>> http://www.sage-p.com/freesoft.htm サポート掲示板 >>> http://www.sage-p.com/kg_ban09/z6037C8.cgi 東日本大震災 >>> http://www.sage-p.com/saigai.html メール >>> ts-neko◇sage-p.com ←◇を@に変えてください 緊急メールは件名に「うどんメール」を付けてください。 このメルマガの登録・解除 - http://www.mag2.com/m/0000083983.htm