LINTを見直した話
僕は基本的にLINTが大嫌いで、理由は
- いくつかのLINTはあまり上手く実装されていない
- いくつかのよくあるルールは、プログラミング言語の設計者がわざと導入したルールを制限するものである
という二つが主である。(既に使われているLINTにわざわざ文句は言わないし、開発チームで決めたことには従いますが。)一番ばかばかしいと思うルールの一つに、
- リストの最後のカンマを入れるか入れないか
がある。これなんかは、設計者がわざわざ導入した自由を逆に制限するものであり、しかも見た目が揃う以外の利点がなにもないルールなので、こういうルールを有効にするのは止めたほうが良いと真顔で発言できる。
で、ずっとLINT嫌いの立場を貫いてきたんだけど、実はLINTって便利じゃないかと思ったことがあるので、書いておきたい。
OCLintのCoveredSwitchStatementsDontNeedDefault
を知って、もしかしたらLINTって便利なものなのかもしれないと、不明を恥じたのだった。これは、Objective-Cプログラムのswitch
が網羅的な場合にdefault
があったら警告するもので、つまり無駄な空のdefault
を書かなくて良くなる効果がある。
switch (enumValue) { case SomeCase: ... break; case AnotherCase: ... break; default: // Unreachable NSAssert(false); break; }
みたいなプログラム、皆さん書きますよね。現時点ではdefault
はいらないんだけど、将来にenumのcaseが増えたことを考えると、default
を書いておいてせめて実行時にはエラーになって欲しい。でもこのdefault
とか明らかに無駄なので、できればソースコードから無くしてしまいたい。
この葛藤から逃れられるのであれば、LINTは使うべきだなあと思ったのでした。
これは、止めて欲しいと思うルールとなにが違うかというと、
- 止めて欲しいのは、ある種のプログラムを書くことを禁止するルール
- 良いと思うのは、コンパイラの賢さが足りないせいで保守的にならざるを得なくてこれまで書けなかったプログラムを、書けるようにするルール
と言える気がする。
なお、OCLintのCoveredSwitchStatementsDontNeedDefault
について言えば、最近のClangはNS_ENUM
とかの新しい構文を使って定義したenumであれば網羅性の検査をしてくれるので、特にOCLintを使う必要はありません。(Cの素朴なenum
を書くのを禁止するルールがないかなーと思って眺めてたら見つけました。)