Python.use(better,"K&R")《23》switch(1)なぜ switch は不要か

記事一覧《こちらに移動中です》2007年10月31日 (水)

Python.use(better, follow=”K&R”) # for novice

《23》switch(1)なぜ switch は不要か《Jython2.5.0》

《著》後藤いるか・小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第1版♪2003/05/23

■ 概要

goto と並んで悪名高いのが switch です。構造化プログラミングには心強い味方であり、old-timer にも根強い人気ですが、オブジェクト指向プログラミングには、逆に switch が手枷足枷となります。

この連載では、K&R の名著 "The C Programming Language" を読み解きながら、Python によるオブジェクト指向プログラミングへの扉を開きます。

■ 関連記事

前の記事次の記事

なぜ switch が(必要)ないのか

goto と並んで悪名高いのが switch ですが、伝統的な構造化プログラミング〔SP〕を好む old-timer には、変わらず根強い人気があるのも事実です。
Python では、オブジェクト指向プログラミング〔OOP〕はオプションであり、それを強要されたりはしません。しかし、洗練された OOP を習得したいなら、goto/switch への未練を断ち切れるかが鍵になります。
よく「Python には switch もないのか」という話を耳にします。ここで「Python にはなぜ switch が必要ないのか」を理解するのが、OOP への「近道」です。
「2007 年問題」が現実になり、高齢化社会への扉が開かれた今だから old-timer への配慮なのか、三項演算子を連想させる構文が導入されました。近い将来、Python にも switch が導入されるなら、old-timer には朗報かもしれません。しかし、それは 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 文は(コンパイル時に)確定できる条件下で処理を選択したい」ときには便利です。そのため、伝統的な switch を用いる戦略は「ハードコーディング」の典型とも言えます。

K&R, p.59】
#include 
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 のリリースに含まれるものです。Python には、組み込み型 bag はありませんが、もしあると話は簡単です。

    counter = bag()
    for line in file(name):
        for e in line:
            counter.add(e)

単に、メソッド add を利用して要素(任意の文字)を追加するだけです。ここで bag とあるのは、Smalltalk/OCL の規定に準拠したものです。詳細は、関連記事で紹介します。
《ひよ子のきもち♪2007/09/26》
==================================
後藤いるか 著 ◆ 監修:小泉ひよ子とタマゴ倶楽部

Last updated♪2009/08/06