なぜ開発者はLinterを嫌うのか?


本記事はWhy developers hate linters?の意訳です。
免責事項:Linterを大好きな方々もいることを知っています。これは私見であり、意見を押し付けるつもりはありません!
私はシニア開発者として、さまざまなチームや技術スタック、組織文化で働いてくる中で、Linterに関してさまざまな経験をしてきました。Linterは、ソースコードをプログラマブルにチェックし、スタイルの一貫性や潜在的なエラー、または事前定義されたルールからの逸脱を検出するツールです。
理論上は素晴らしいアイデアです。コーディングスタイルの細かい問題を自動化し、問題が欠陥に発展する前に検出し、コードベースを整然と保ってくれます。しかし実際には、開発者とLinterの関係は単純ではありません。
なぜ、問題が起こるのでしょうか?理論上は、Linterは開発者がより良いコードを書くのを助けるはずです。しかし、多くの開発者がLinterをサポートというよりも、障害と感じています。その理由を理解するには、ソフトウェア開発の文化的、心理的、実際的な側面を深く理解する必要があります。
この記事では、開発現場のエンジニアの実体験やIT業界の声に基づく、Linterと開発の関係に関する緊張感を詳しく紹介します。
警告疲れと誤検知
多くの分野で知られている「警告疲れ」という概念があります。人は多数の重要ではない、または誤った警告を受け取り続けると、それを無視するようになる現象です。Linterでも同じことが起こります。Linterが厳しすぎる場合、重要ではない多くの問題を指摘しますが、それらは本当のバグではないことが多いのです。徐々に、開発者はこれらの警告を無視し始めます。結果として、重要なアラートがノイズの中に埋もれる可能性があります。
誤検知とは、Linterが実際には問題のないコードやパターンを誤って指摘することです。開発者は誤検知の頻発によって、ツールの有用性や設定が正しくないと感じてしまいます。
{
"rules": {
// 圧倒的なスタイルルール
"quotes": ["error", "single"],
"semi": ["error", "always"],
"indent": ["error", 2],
"comma-dangle": ["error", "always-multiline"],
"arrow-parens": ["error", "always"],
"max-len": ["error", { "code": 80 }],
// 本当に重要なルールがノイズに埋もれる
"no-eval": "error",
"no-implied-eval": "error",
"security/detect-object-injection": "error",
// 誤検知を生むルール
"no-unused-vars": "error",
"no-unreachable": "error",
"no-unsafe-optional-chaining": "error",
"typescript-no-unused-vars": "error",
"@typescript-eslint/no-unused-vars": "error"
}
}
さらに、Linterはしばしばルールセットを巡る「宗教戦争」を引き起こします。一度特定のスタイルガイド(例えばAirbnbスタイルガイド)が採用されると、チームメンバーが設定を調整しようとする際に反発を招くでしょう。環境は硬直的で柔軟性なく、結果として開発者とLinterの関係は悪化します。
柔軟性の欠如と文脈のニュアンス
Linterの大きな課題の一つは、文脈を理解する能力がないことです。コードには、しばしば単純なルールベースのツールでは理解できないニュアンスがあります。例えば、特定のコード構造がスタイル規則に違反しているように見えても、特定のシナリオでは合理的なのです。しかし、Linterはそのようなコンテキストを理解せず、ただルール違反としてフラグを立てます。
以下の例では、マトリックス操作の可読性が縦方向の配置によって向上しています。
def transform_matrix(matrix):
return [
[1, 0, 0], # Linter: 行末の空白
[0, 1, 0], # Linter: 行末の空白
[0, 0, 1] # Linter: 行末の空白
]
# Linterが強制するコード:
return [[1,0,0],[0,1,0],[0,0,1]] # 「修正済み」だが可読性が低下
この結果、開発者はLinterを満足させるために、不自然で直感的でないコードを書く羽目になります。
自動的な完全性の幻想
もう一つの微妙な問題は、チームがLinterをコード品質の万能薬と見なしてしまうリスクです。Lintチェックに合格すれば、コードが良いものだと錯覚する可能性があります。特にマネージャーや新人の開発者は、Lintチェックを通過したからコードが問題ないと信じてしまう傾向があります。
実際には、Linterはさまざまな開発ツールの1つのツールに過ぎません。Lintへの過度な依存は、ピアレビューやアーキテクチャレビュー、徹底的なテストといった重要な実践を軽視する可能性があります。その結果、真に重大な問題が見落とされるかも知れません。それは、チーム全員が特定のコーディングスタイルの遵守に夢中になってしまうからです。経験豊富な開発者は、スタイルチェックの自動化が人間の判断や優れたエンジニアリングプラクティスに取って代わるという考えに賛同できないでしょう。
権力や管理の乱用としての認識
Linterが管理ツールとして使われているように感じることはないでしょうか。例えば、チームやリード開発者が極めて厳格なルールを設定し、それを押しつけると、メンバーは細かく管理されているように感じます。小さなコミットごとにLintエラーが発生し、スタイル対応を求められる。このような状況が続くと、開発者は自身の専門性や判断が信頼されていないと感じるでしょう。コーディングスタイルが、協力の場ではなく力関係の戦場になってしまうのです。
このような反発は実際に存在します。ガイドとマイクロマネジメントの間の境界線は非常に曖昧です。開発チームは信頼と尊重、そして自律性によって成り立っています。Linterが誤用されると、それらがすべて損なわれる可能性があります。
創造的自由の喪失
プログラミングは、コンピュータに何をさせたいかを伝えるアートです。我々は常にすべてのアートを科学へと変える努力をすべきです:その過程で、アートを進歩させるのです – ドナルド・クヌース『プログラミングの技法』
ソフトウェア開発の本質は、技術的な正確さと創造的な表現の融合です。開発者は職人のようにコードを作り、自身の理解や経験を踏まえた上で、特定構造やスタイルを選択します。しかし、Linterが厳格なルールを強制すると、この創造的な要素が抑圧されてしまいます。
たとえば、複雑なコードスニペット(関数など)をリファクタリングして、読みやすく保守可能なコードにしたものの、Linterによって分割や形式変更を強制される場合があります。その結果、コードは開発者の思考プロセスを反映したものではなく、機械的なフォーマットの産物となります。一貫性にはメリットがあり、特にチーム開発では重要です。しかし、機械的な強制は、コーディングの技術を損ない、独自のスタイルを持つ経験豊富な開発者にストレスを与えるでしょう。
メリットとデメリットのバランスを取る
これらの理由はあれど、Linterが本質的に悪いというつもりはありません。Linterは、適切に使用すれば非常に価値のあるツールになります。キーは、バランスです。本当のエラーを検出したり、可読性や一貫性を改善したりする、最低限のスタイルルールの適用にフォーカスすべきです。
Linterを「正しい」または「間違った」コードの判断として扱うべきではありません。スタイルルールを緩めた方が、より明確で安全、または保守可能なコードになる場合は、例外を認めましょう。どのルールが重要で、またはそうではないかをチーム全体で決定する方が重要です。
良いLint利用の実践
小規模で始めて反復する: 大規模で完全に厳格な設定を、レガシーコードベース に対して一気に適用しないようにしましょう。一般的なバグや、明白なスタイル問題を解決する小さなルールセットから始め、徐々に拡張していきましょう。開発者が順応する時間が必要です。
ルールにチームの意見を反映: スタイルガイドを一方的に決めるのではなく、チーム全体の意見を取り入れましょう。チームのコンセンサスと実用性を目指し、ルールセットは可能な限り最小限に抑えます。
文脈を考慮: 特定の場合において、ルールを無効にすることを許容しましょう。コメントを使って例外を簡単に記載できるようにし、そうした例外が正当化されるようにします。
大きな利益に焦点を: 一般的なエラーを防ぐ、読みやすさを向上させる、またはパフォーマンスの問題を検出するルールに重点を置きましょう。美的なルールは特定の目的を果たす場合を除いて、優先度を下げましょう。
定期的な再評価: コードベースが進化し、チームが変化するにつれて、Lintのルールを見直しましょう。1年前に意味のあったルールが、今では意味を成さない場合もあります。
まとめ
本記事の結論として、Linterを捨てるべきだとは考えていません。ただし、Lintをどう実装するかについて、よく考えましょう。
システムの複雑さが増し続ける今日では、一貫性を促進して小さなエラーを検出するツールは大事です。ただし、そうしたツールの限界を認識し、コードを書くという本来の目的を尊重しなければなりません。
CodeRabbitでは、AIを活用したコードレビューによってLintツールを補完し、コンテキストに応じた提案や意味論的な理解を提供します。そして、表面的なフォーマットを超えた意味のあるコードの改善を実現しています。ぜひお試しください。
Subscribe to my newsletter
Read articles from Atsushi Nakatsugawa directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
