Oddwit


foreachで(僕が)よく引っかかる罠

Posted in PHP, Programming by マルコ on the February 12th, 2007

PHPで配列を扱うときは、中身をイテレートしてくれる foreach が必需品だ。

foreach ($var as $key=>$value){
	echo $value;
}

でもあまり無防備にコードを書いていると、それまでずっと機嫌よく動いていたスクリプトが突然醜いエラーを吐くことがある。

Warning: Invalid argument supplied for foreach() in index.php on line 3

これは $var が配列でなかった場合に起こってしまう。こういうコードを書くときは $var が必ず配列だと思い込んでいることが多いが、実際には特定の条件下で null だったりすることがたまにある。

そこで、foreach に配列を入れる際に必ず配列型かどうかをチェックしたほうがよい。

if (is_array($var)){
	foreach ($var as $key=>$value){
		echo $value;
	}
}

もしくは、配列型にキャストしてもよい。こちらの方がコードは読みやすい。

foreach ((array)$var as $key=>$value){
	echo $key." : ".$value;
}

ちなみに null を配列にキャストすると、空の配列になる。つまりそのまま何事も無かったかのように foreach をスルーできる。それ以外のものをキャストすると要素を一つだけ持った配列になるということも、キャストで foreach を使うなら覚えておいた方がいい。

コードを読む能力

Posted in Programming by マルコ on the February 7th, 2007

こちらのブログ「/home/siddhi」に、大卒で就職試験に来る志望者たちの実力不足を嘆く記事があった。特にコードを読む能力について書かれているが、下のような簡単な問題を出したところ、まともに答えられる人が少なくて驚いたというのだ。

問:この関数fは何をしているか。

int function f(somestruct *a) {
    int x = 0;
    if (NULL == a) {
        return 0;
    }
    x += f(a->left);
    x += 1;
    x += f(a->right);
    return x;
}

そして僕は見事に解けなかったわけだ。というか、20秒ほどにらめっこした後、答を見てしまった。答を見てしまうとそれはもう簡単な問題である。答を出せなかった自分がとても恥ずかしくなった。これはなかなか危機感を誘う事実だ。これでは先のブログで嘆かれる無能な新卒まっしぐらである(まだ卒業しないが)。

で、コードを読む能力が高いというのはどういうことなのかを少し考えてみた。

ひとつには、単純に論理力があればコードを読解できるはずである。たとえば上の問題ならば、関数が int を返している時点で何らかの数か数値を求める関数だと分かる。あとは再帰構造を頭の中で実行する思考力があれば、少し時間はかかっても答が出せるはずだ。

問題は、「少し時間がかかっても」というところである。ここで、プログラミングのクリシェに関する知識量がものをいう。クリシェがなぜ存在するか。いちいち考えていると長くなる問題のうち、利用価値の高いものがクリシェとして残っているのだ。つまり知識があれば考える必要がない。上の問題ならば、a が left と right というプロパティを持っていると見た時点で木じゃないかと思えれば、あとは int を返していることから数を数えているのかもしれないという前提をもって脳内実行に取り掛かれるから、答を出すのが格段に早くなる。

ところで、ここまでアルゴリズムについて話してきたが、プログラミングにはこれとはまた違った次元があると思う。アルゴリズムの少し斜め上、デザインパターンの次元だ。僕はいま、アンケート作成のWEBアプリを作っているが、実際僕はこちらの次元を徘徊している場合が多い。作業の大部分はともすれば設定ファイルで済んでしまいそうな内容で、「アルゴリズム」と呼ぶと大仰だ。いうなればプログラムというよりマークアップなのである。が、なぜマークアップだけでプログラムができるかと言うと、その下にデザインパターンがあるからだ。

この次元のコードを読むにはデザインパターンの知識がものを言う。だがこちらは、書いた人がパターンに関する間違った認識を持っている場合や、そもそもパターンを使っていない場合を想定しなければならない。つまりは脳内の空間でいかに忠実にプログラムを実行できるかの占める割合が大きいのではないだろうか。肝になるのは論理力、想像力だ。

コードを読む力は作業効率にかかわる。先のブログに出ていた例だが、たとえばポールがケビン先輩のコードを使って別の機能を開発するとしよう。ここでポールはケビン先輩のコードを読んで仕組みや意図を汲み取らなければいけない。そうでないと、ポールは「正しい」コードを書くことができず、結果的にコードをハックし、プログラムはスパゲッティ状態に陥る。このようなことは少ない経験の中にたしかにあった。(しっかりドキュメントしろ、というような話は今はおいておくとして。)

そして当然、読めなければ書けるわけがないのである。

常日頃から思考力を鍛えておきたいものだ。デザインパターンやアルゴリズムに関する知識もしっかり蓄えておく必要がある。

本文中にヒントも出たが、上の問題の答は、「二分探索木のノードの数を求める」だった。解けましたか?

訂正:正確には「二分木」でした。
追記:「a が left と right というプロパティを持っている」事に加えて、left も right も a と同じ構造体であることが重大なヒントでした。やはりこれくらいはすぐに読み取れるようになりたい。

« Previous Page