« 「ETC利用率が50%突破」ったってなぁ... | Main | 自転車納車 »

October 13, 2005

プログラミングのセンス

某掲示板でのやりとりより。以下は Java での話なので、Java がわからないとちょっとわかりづらいかもしれません。

元の質問は


Boolean hoge;
--省略
return hoge == null ? false : hoge.booleanValue();

で「最後の文の意味がわかりません」という、要するに「三項演算子を見たことなくて意味がわかりません」というものでした。すぐに「三項演算子ですよ。入門書とかを読んでくださいね」と回答がついて質問者も納得したのですが、

余計なことに「それ、あまり良くない書き方ですね」と書いてしまった人がいるんですね、いや私なんですが(苦笑)。あ、もちろん「蛇足の話で恐縮ですが」と断りを入れましたよ。
で、その根拠、の前に上記のプログラムの解説をちょっとしましょうか。

(1) Boolean型 hoge を宣言(明示的に初期化をしていないので hoge には null が入る)
(2) 省略された部分でもしかしたら hoge が何らかのインスタンスを差すようになっているかもしれないし、null のままかもしれない。
(3) メソッドの最後で、以下の判定をして値を返す
(3-1) hoge が null ならば false を返す
(3-2) hoge が null でなければ、hoge が差しているインスタンス(Boolean オブジェクト)の booleanValue() を返す

三項演算子の部分(3) は

(条件) ? (条件が true の時の値) : (条件が false の時の値)

という構文。

Boolean#booleanValue() は true か false を返すメソッド。

要するに(3)は「hoge.booleanValue() を返したいんだけれど、hoge が null だったらまずいからそれを避けるコードが付加されたもの」であるわけです。

で、「悪い書き方」である理由。

(a) hoge の宣言時に初期値として Boolean.FALSE を入れておけば、以降 null チェックなんて必要ない。
(b) 三項演算子部分は「条件が true 時に、全体は false」と true/false がごっちゃになってて、ぱっと見だと混乱する。こんな書き方をするのなら条件を逆にして、
hoge != null ? hoge.booleanValue() : false
と書くか、さらに
hoge != null && hoge.booleanValue()
にしたほうがわかりやすい。
(c) そもそも、Boolean型オブジェクトである必要があるの ? プリミティブの boolean でいいじゃん。「null のままであることがある」って「三値型」じゃあるまいし。

ということで、以下のようにすることを提案しました。


案 1 あくまで Boolean型を使用
Boolean hoge = Boolean.FALSE; // 初期化する
--省略
return hoge.booleanValue(); // チェックがなくなってすっきり

案 2 boolean にしちゃえば ?
boolean hoge = false;
--省略
return hoge; // booleanValue() を呼ぶ必要さえない


これはこれで悪くないはずで、まだ書いていないならこのようにするのがいいのですが、既存のものを書き換えるとなると、「--省略」部分にどのような影響が出るか、とくに後者はオブジェクトですらなくなったのでいろいろと検証が大変かもしれません。私もそこには気づいていましたが、もっと余計なことに脱線してしまいそうであえて触れずにしておきました。

ところがその後、ある人がこのようなコードを示しました。


return Boolean.TRUE.equals(hoge);

注: equals() には null を渡しても害がなく、そのときには false を返すことが一般的に保証されています(そうじゃない equals() は書くべきではない、とまで言われています)。

目から鱗というかコロンブスの卵というか、驚きました。そういえば

"constant string".equals(stringObject) ← stringObject が null の時でも大丈夫

とはよく書いたのに、Boolean には応用できませんでした。たったこうするだけで、宣言時に初期化をしていなかろうと「--省略」部で hoge が null のままのことがあろうと、元のプログラムの意図通りの結果を返します。上記のようにだらだらと説明したのが虚しくなるほどの簡潔さです。

なんていうか「こういうものがパッと出てくること」こそが「プログラミングのセンスがある」ということなんじゃなかろうか、と思い知らされた感じです。まだまだ精進が足りないなぁ...。

|

« 「ETC利用率が50%突破」ったってなぁ... | Main | 自転車納車 »

Comments

そもそも「可読性の高いソースを書く」って観点からすると、三項演算子なんか使うな、なんだけど(笑)。

#昔やってたPJのコーディングルールでは厳禁だったな

そういう意味では、案2が正解。
equals()メソッド使うのは、「エレガントなやり方」ではあるけど、可読性の点ではやや劣るかね。

Posted by: あくあ | October 13, 2005 at 17:38

Post a comment



(Not displayed with comment.)


Comments are moderated, and will not appear on this weblog until the author has approved them.



TrackBack

TrackBack URL for this entry:
http://app.cocolog-nifty.com/t/trackback/6718/6380091

Listed below are links to weblogs that reference プログラミングのセンス:

« 「ETC利用率が50%突破」ったってなぁ... | Main | 自転車納車 »