ポリデント <p>ソフトウェアに潜むポリデントの話。</p> <!-- waf_thread::toc --> <h2 id="indent"><a class="permalink-anchor permalink-anchor-head" href="#indent"><!----></a>インデント</h2> <p>インデントとは、木構造のある行の列をテキストで表現するとき行頭に詰める空白文字、あるいはその行為のことである。</p> <pre class="giallo" style="color-scheme: light dark; color: light-dark(#3C3836, #EBDBB2); background-color: light-dark(#FBF1C7, #282828);" data-lang="c"><code data-lang="c"><span class="giallo-l"><span style="color: light-dark(#AF3A03, #FE8019);">int</span><span style="color: light-dark(#B57614, #FABD2F);"> main</span><span style="color: light-dark(#7C6F64, #A89984);">(</span><span style="color: light-dark(#AF3A03, #FE8019);">void</span><span style="color: light-dark(#7C6F64, #A89984);">)</span><span style="color: light-dark(#7C6F64, #A89984);"> {</span></span> <span class="giallo-l"><span style="color: light-dark(#9D0006, #FB4934);"> return</span><span style="color: light-dark(#8F3F71, #D3869B);"> 0</span><span style="color: light-dark(#7C6F64, #A89984);">;</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;">↑この空白がインデント</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);">}</span></span></code></pre><pre class="giallo" style="color-scheme: light dark; color: light-dark(#3C3836, #EBDBB2); background-color: light-dark(#FBF1C7, #282828);" data-lang="markdown"><code data-lang="markdown"><span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);">*</span><span> 項目</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> +</span><span> リストアイテム1</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> +</span><span> リストアイテム2</span><span style="color: light-dark(#928374, #928374);font-style: italic;"><!--</span></span> <span class="giallo-l"><span>↑この空白がインデント--></span></span></code></pre><h3 id="indentation-style"><a class="permalink-anchor permalink-anchor-head" href="#indentation-style"><!----></a>インデントの流儀</h3> <p>インデントには、「何をいくつ詰めるか」で複数の流儀がある。 (これらはしばしば俗に言う「宗教戦争」のテーマとなっているが、今回それには触れない。)</p> <p>いくつか例を挙げよう。</p> <ul> <li>1レベルごとに空白 (0x20, <code>' '</code>) を2文字</li> <li>1レベルごとに空白を3文字</li> <li>1レベルごとに空白を4文字</li> <li>1レベルごとに水平タブ (0x09, <code>'\t'</code>) を1文字</li> <li>1レベルごとに空白を2文字、ただし4レベル分 (空白8文字分) ずつまとめて水平タブに置き換える</li> <li>1レベルごとに空白を4文字、ただし2レベル分 (空白8文字分) ずつまとめて水平タブに置き換える</li> </ul> <h3 id="mixed-indentation-of-tabs-and-spaces"><a class="permalink-anchor permalink-anchor-head" href="#mixed-indentation-of-tabs-and-spaces"><!----></a>水平タブと空白の混合</h3> <p>空白が増えてきたらまとめて水平タブに置き換える流儀では、エディタのタブ幅によって表示が壊れやすい。 標準的なターミナル等では水平タブは8文字幅だが、テキストエディタの設定によっては4文字幅で表示する場合などがあるからだ。 プロジェクト側でタブ幅の設定ファイルを持ちテキストエディタにそれを優先させるという手段で回避できるが、とにかく一手間必要になる。</p> <pre class="giallo" style="color-scheme: light dark; color: light-dark(#3C3836, #EBDBB2); background-color: light-dark(#FBF1C7, #282828);" data-lang="c"><code data-lang="c"><span class="giallo-l"><span style="color: light-dark(#AF3A03, #FE8019);">void</span><span style="color: light-dark(#B57614, #FABD2F);"> foo</span><span style="color: light-dark(#7C6F64, #A89984);">(</span><span style="color: light-dark(#7C6F64, #A89984);">)</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> {</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;"> ↑空白2つ</span></span> <span class="giallo-l"><span style="color: light-dark(#9D0006, #FB4934);"> if</span><span style="color: light-dark(#7C6F64, #A89984);">(</span><span>bar</span><span style="color: light-dark(#7C6F64, #A89984);">)</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;"> ↑空白4つ</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> {</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;"> ↑空白6つ</span></span> <span class="giallo-l"><span style="color: light-dark(#B57614, #FABD2F);"> baz</span><span style="color: light-dark(#7C6F64, #A89984);">(</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;"> ↑タブ文字1つ</span></span> <span class="giallo-l"><span> qux0</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;"> ↑タブ文字1つ + 空白2つ</span></span> <span class="giallo-l"><span> qux1</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span> qux2</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span> qux3</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> )</span><span style="color: light-dark(#7C6F64, #A89984);">;</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> }</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> }</span></span></code></pre> <p>こうしたブロックレベルを表現する場合では、水平タブと空白の混合は (たしかに実在はするものの) 特定プロジェクト等が採用していたりするのみで、頻繁にそこら中でみられるような流儀ではない。 しかし、これが局所的に発生しやすい文脈もある。</p> <pre class="giallo" style="color-scheme: light dark; color: light-dark(#3C3836, #EBDBB2); background-color: light-dark(#FBF1C7, #282828);" data-lang="c"><code data-lang="c"><span class="giallo-l"><span style="color: light-dark(#9D0006, #FB4934);"> if</span><span style="color: light-dark(#7C6F64, #A89984);"> (</span><span style="color: light-dark(#9D0006, #FB4934);">!</span><span>dry_run</span><span style="color: light-dark(#7C6F64, #A89984);">)</span><span style="color: light-dark(#7C6F64, #A89984);"> {</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;">↑タブ1つ</span></span> <span class="giallo-l"><span style="color: light-dark(#B57614, #FABD2F);"> prepare</span><span style="color: light-dark(#7C6F64, #A89984);">(</span><span style="color: light-dark(#7C6F64, #A89984);">)</span><span style="color: light-dark(#7C6F64, #A89984);">;</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;">↑タブ2つ</span></span> <span class="giallo-l"><span style="color: light-dark(#B57614, #FABD2F);"> letsgo</span><span style="color: light-dark(#7C6F64, #A89984);">(</span><span>param0</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span> param1</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span style="color: light-dark(#928374, #928374);font-style: italic;">//</span><span style="color: light-dark(#928374, #928374);font-style: italic;">↑タブ2つ + 空白7つ (!?)</span></span> <span class="giallo-l"><span> param2</span><span style="color: light-dark(#7C6F64, #A89984);">,</span></span> <span class="giallo-l"><span> param3</span><span style="color: light-dark(#7C6F64, #A89984);">)</span><span style="color: light-dark(#7C6F64, #A89984);">;</span></span> <span class="giallo-l"><span style="color: light-dark(#7C6F64, #A89984);"> }</span></span></code></pre> <p>関数定義や関数呼出において引数が多かったり長かったりするとき複数行に跨がることがあるが、このとき最初の引数を別の行にしない流儀では関数名と開き括弧の分 (あるいは、加えて括弧の前の空白分) の空白で引数の先頭が揃うようインデントを追加する派閥がある。 この場合、引数用のインデント幅は関数名の長さに依存し固定幅の水平タブでは表現できないため、どうしても空白文字を使うことになる。 ブロックインデントを水平タブで行っていた場合、めでたくタブ+空白の混合インデントの完成だ。</p> <h2 id="polydent"><a class="permalink-anchor permalink-anchor-head" href="#polydent"><!----></a>ポリデント</h2> <p>水平タブ+空白の混合インデントのように多数 (poly) の種類の空白を用いるインデント (indent) のことを、個人的に<strong>ポリデント</strong>と呼ぶことにしている。</p> <p>この記事はこれを紹介するためだけに書かれた。</p> <h2 id="appendix"><a class="permalink-anchor permalink-anchor-head" href="#appendix"><!----></a>おまけ</h2> <ul> <li>ポリデントが “宗教戦争” のオチ要員として使われている例: <a rel="external" href="https://www.emacswiki.org/emacs/TabsSpacesBoth">[Home] Tabs Spaces Both</a></li> </ul>