Python.use(better, by="K&R") # for novice《23》switch(1)なぜ switch は不要か★
♪都合により「 続・ひよ子のきもち 」にお引越し致します。(^_^)/~
★引越し後は(予告なしに)削除しますので、新しい記事をご覧ください。m(_o_)m
-----------------------( きりとれません )-----------------------------
------------ 序 ------------
この連載では、K&R の名著 "The C Programming Language" を読み解きながら、Python によるオブジェクト指向プログラミングへの扉を開きます。
ここで公開している記事は「キーワード検索」を利用するための便宜的なものです。詳細は、正式版(PDF)をダウンロードしてご覧ください。
⇒《準備中》
【目次】関連記事
〔Python/Jython 入門〕Python.use(better, by="K&R") # for novice
《その他の関連記事》
2007年8月18日《21》switch 文は、百害あって一利なし《前篇》
2007年8月25日《22》switch 文は、百害あって一利なし《後篇》
※ goto 文と並んで悪名高いのが switch 文です。構造化プログラミングにとっては心強い味方であり、old-timer には根強い人気のある switch 文ですが、オブジェクト指向プログラミングにとっては、逆にその switch 文が手枷足枷となります。switch 文は、ハードコーディングの典型でもあり、GoF 本にもその弊害について言及してあります。
では、OOP では、switch や if/else の羅列を使わずに、どのようにして問題解決を図るのでしょうか。
《査読中》
------------ 本文 ------------
《23》switch(1)なぜ switch は不要か★
伝統的なプログラミングの象徴でもある switch を卒業して、オブジェクト指向プログラミングの恩恵に浴するなら、 要求仕様の変更にも柔軟に対処できるように実行中に拡張可能なコードを、自由自在に記述できるようになります。
なぜ switch がないのか:goto 文と並んで悪名高いのが switch 文です。伝統的な構造化プログラミング(SP)を好む old-timer には、変わらず根強い人気があります。Python にとって、オブジェクト指向プログラミング(OOP)はオプションであり、強制されるものではありません。しかし、Ruby/Python に限らず、洗練された OOP を体得しようとするなら、goto/switch は、手枷足枷となり、越えなければならない壁のひとつです。よく「Python には switch もないのか」という話を耳にしますが、「Python にはなぜ switch がないのか」ということに気付いたら、OOP の神髄に、また一歩近づけます。ちなみに、Python と同様に、Smalltalk にも switch はありません。これらはただの偶然でしょうか。2007 年問題が現実となり、高齢化社会への扉が開かれた今、old-timer への配慮なのか、三項演算子(条件演算子)に相当する構文が導入されました。近い将来、switch が導入されるなら、old-timer には吉報かもしれません。しかし、それは OOP を体得する好機を逃すばかりか、OOP を理解するための扉を永遠に閉ざしかねません。《ひよ子》
【K&R, p.58】"The switch statement is a multi-way decision that tests whether an expression matches one of a number of constant integer values ..." とあるように「switch 文は、特定の整数値によって分岐される処理を列挙した構造」となります。しかし、SP の定石である switch を用いた戦略は、ハードコーディングの典型です。
【K&R, p.59】
#include <stdio.h>main() /* count digits, white space, others */
{
int c, i, nwhite, nother, ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; i++)
ndigit[i] = 0:
while ((c = getchar()) != EOF) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
ndigit[c-'0']++;
break;
case ' ': case '\n': case '\t':
nwhite++;
break;
default:
nother++;
break;
}
}
printf("digits =");
for (i = 0; i < 10; i++)
printf(" %d", ndigit[i]);
printf(", white space = %d, other = %d\n",
nwhite, nother);
return 0;
}
K&R で紹介された実現方法では、入力された文字を判定するために、switch 文が必要でした。伝統的な SP では重宝される switch 文ですが、純粋な OOP では手かせ足かせとなります。switch 文と別れることができれば、また一歩、OOP の神髄へと近づけます。switch 文の呪縛から逃れるにはさまざまな手法がありますが、今回は、辞書 map を使った手法を紹介します。他の方法は、関連記事が参考になります。
name = "src/symbol.py"
counter = {}
for line in file(name):
for e in line:
if e in counter:
counter[e] += 1
else:
counter[e] = 1
その前に、文字の出現頻度を求めるだけなら、話は簡単です。ここでは、標準入力の代わりに、任意のファイルに含まれる文字を対象としています。ここで "symbol.py" とあるのは、Python 2.5 のリリースに含まれるソースコードのひとつです。
counter = bag()
for line in file(name):
for e in line:
counter.add(e)
Python には、組み込み型 set がありますが、もし bag が組み込み型なら、話は簡単です。単に、メソッド add を利用して要素(任意の文字)を追加するだけです。ここで bag とあるのは、Smalltalk を参考に実現したものです。詳細は、関連記事を参照してください。
では、switch 文の呪縛を逃れて、SP から OOP へと脱皮するには、どうすれば良いのでしょうか。パート(2)へ続く。
《ひよ子のきもち♪2007/09/26》
==================================
後藤いるか 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部
| 固定リンク
« Python.use(better, by="K&R") # for novice《22》二分木(7)Dynamic Class★ | トップページ | Python.use(better, by="K&R") # for novice《24》switch(2)switch は禁断の木の実★ »
「.連載: Python.use(better, anti="GoF") # GoForward」カテゴリの記事
- ♪ Python.use(better, anti="GoF") # Let's GoForward(2007.08.25)
- Python.use(better, anti="GoF") # Let's GoForward《26》Visitor(6)パターン夜明け前★★(2007.09.03)
- Python.use(better, by="K&R") # for novice《23》switch(1)なぜ switch は不要か★(2007.09.26)
- Python.use(better, anti="GoF") # Let's GoForward《29》Visitor(9)パターンの夜明け★★(2007.09.06)
- Python.use(better, by="K&R") # for novice《25》switch(3)脱・ハードコーディング★(2007.09.28)
「.連載: Python.use(better, by="K&R") # for novice」カテゴリの記事
- Python.use(better, by="K&R") # for novice《23》switch(1)なぜ switch は不要か★(2007.09.26)
- ♪ Python.use(better, by="K&R") # for novice(2007.06.24)
- Python.use(better, by="K&R") # for novice《50》特殊メソッド __getitem__(2008.01.11)
- Python.use(better, by="K&R") # for novice《49》特殊メソッド __contains__(2008.01.10)
- Python.use(better, by="K&R") # for novice《48》特殊メソッド __nonzero__(2008.01.09)
「C#/Visual Studio」カテゴリの記事
- Python.use(better, anti="GoF") # Let's GoForward《26》Visitor(6)パターン夜明け前★★(2007.09.03)
- Python.use(better, by="K&R") # for novice《23》switch(1)なぜ switch は不要か★(2007.09.26)
- Python.use(better, anti="GoF") # Let's GoForward《29》Visitor(9)パターンの夜明け★★(2007.09.06)
- Python.use(better, by="K&R") # for novice《50》特殊メソッド __getitem__(2008.01.11)
- Python.use(better, by="K&R") # for novice《49》特殊メソッド __contains__(2008.01.10)
「JML/Java/Eclipse」カテゴリの記事
- Shall_we_Agile = Java.use(better, Python) # Swing《6.5》モジュール:jarray(2008.04.25)
- Java.use(better, Jython)《61》アジァイル開発:要求仕様の変更★(2008.03.03)
- Python.use(better, GUI=Tkinter)《33》事例:ヒストグラムと2値化(3)★★(2007.02.21)
- 連載: Java.use(better) Jython はじめました《11》JavaBeans(1)値の参照と変更(2007.09.10)
- Shall_we_Agile = Java.use(better, Python) # Swing《43》JList(3)選択したらどうなるの★(2007.05.30)
「Jython/Python」カテゴリの記事
- Shall_we_Agile = Java.use(better, Python) # Swing《6.5》モジュール:jarray(2008.04.25)
- 【準備中】連載: Java.use(better) Jython はじめました《1》文字列とリスト(1)★(2006.07.10)
- Java.use(better, Jython)《61》アジァイル開発:要求仕様の変更★(2008.03.03)
- Python.use(better, GUI=Tkinter)《33》事例:ヒストグラムと2値化(3)★★(2007.02.21)
- 連載: Java.use(better) Jython はじめました《11》JavaBeans(1)値の参照と変更(2007.09.10)

コメント