2006年04月30日 03:46 [Edit]

タブのスペース化はタブ幅よりも重要である

あえて断言します。君たちは半分しかわかっていないと。

Charsbar::Note - タブとスペースの話
あえて断言しときます。こんなモンはバッドノウハウなんであって、ベストプラクティスでもなんでもない、と。
最速インターフェース研究会 :: タブとスペースと萌ディタの話
なんかそもそもタブを使わずにスペース4で統一せよってのはフォントサイズをピクセル単位で指定したがるデザイナの言い分みたいで気に食わない。

君たちは、patchのことをきれいさぱーり忘れている。

人のコードを直したり、人にコードを直してもらったりしなくてもいいというのであれば、君たちのいい分ももっともだ。しかし、人とコードをやりとりする時にpatchをやりとりする場合、tabは頭が痛い以外の何者でもない。

以下に二つのファイルがある。

old.pl
#!/usr/bin/env perl
use strict;
use warnings;
sub spc2tabs{
    my $str = shift;
    my @lines = split /\n/, $str;
    for (@lines){
        s{^( +)}{ "    " x (length($1)/4) }eg;
    }
    return join("\n", @lines) . "\n";
}
while(<>){
    print spc2tabs($_)
}
new.pl
#!/usr/bin/env perl
use strict;
use warnings;
sub spc2tabs{
    my $str = shift;
    my @lines = split /\n/, $str;
    for (@lines){
        s{^([ ]+)}{ "\t" x (length($1)/4) }egxms;
    }
    return join("\n", @lines) . "\n";
}
while(<>){
    print spc2tabs($_)
}

この二つのdiffを取ると、たいていのshell (tabstop = 8)ではこう見えるはずである。

--- old.pl      2006-04-30 03:21:14.000000000 +0900
+++ new.pl      2006-04-30 03:21:05.000000000 +0900
@@ -5,7 +5,7 @@
     my $str = shift;
     my @lines = split /\n/, $str;
     for (@lines){
-               s{^( +)}{ "     " x (length($1)/4) }eg;
+        s{^([ ]+)}{ "\t" x (length($1)/4) }egxms;
     }
     return join("\n", @lines) . "\n";
 }

これをファイルに落とさず、そのままshellからコピペした場合、それがtab characterだったかspaceだったかという情報は失われ、そしてそれを当てたメンテナが泣かされることになる。この程度であればpatchは賢いのでなんとかpatchは当たるが、当てたとしてもまたそこをindentしなおす羽目になるし、最悪patchが当たらなくなり、手で当てる羽目になるのだ。

これに何度泣かされた事か。

tab characterを混じらせる罪に比べたら、tab stopを4にしない罪などずっと軽いのだ。実際EncodeのFouderである、Nick Ing-Simmonsのtab stopは何と1であり、その名残はenc2xsなどに残っている。私が彼に敬意を表したのだ。とはいえ、私が新たに書き加えたところは標準的な4にはなっているが。

そういうことをプログラマが(多様性が美徳のPerlプログラマが)、言うことに、なんか引っかかりを感じる。行頭以外の箇所でタブを使ってるとひどいことになるけれど、それさえしなければ後は個人が好きにできるようにタブでインデントした方が良いんじゃないの?って思うんだけど。

それは多様性をはき違えている。多様性は自分のスタイルを他人に押し付けることじゃない。他人のスタイルを受け入れることだ。そして他人のスタイル、そしてコードを受け入れる際に、tabは邪魔になるのだ。それほどtabが好きなら

perl -i.bak -ple 's{^([ ]+)}{"\t" x (length($1)/4)}e' *.pl

でtabifyできるではないか。

ただし、人にpatchを送るときには、必ず

perl -i.bak -ple 's{^(\t+)}{q( ) x (length($1)*4)}e' old.pl

としていただきたい。

Dan the Maintainer of the Largest Core Module


この記事へのトラックバックURL

この記事へのトラックバック
とりあえず困っている方へ Emacs でインデントにタブを使う方法を。最初っからタブにしたいけど hook を使わないとできなかった。 ;; 例えば c-mode (add-hook 'c-mode-hook '(lambda () (setq in...
タブとかスペースとか【日々実験中】at 2006年08月05日 14:42
ボクはスペースやタブの問題の解決はツールの責務なんじゃないかな,と思う.
タブとスペースのことを考えると頭が痛くなります...【32nd diary】at 2006年05月01日 01:30
自分がソースを書くときは、入力するときはもちろん4桁ごとのタブを使うけど、 ファイルに保存する前に全て半角スペースに変換している。 秀丸エディタでは、CTRL+A → ALT+E → V → S とするとスペースに変換できる。 たぶん、0.2 秒くらい。(計ってないけど) これ...
タブとスペースのベストプラクティス(平和主義)【ゆうすけブログ】at 2006年04月30日 20:44
なんだか、こういうOneLiner が紹介されてました。 空白文字列の連続を 制御文字タブに置き換えるというものです。(おそらく) これってこんな感じの正規表現じゃ駄目なんでしょか??
[bin]Perl OneLiner【技術メモ帳】at 2006年04月30日 17:45
コードを書くときのインデントをタブにするのかスペースにするのかという話。 Charsbar::Note - タブとスペースの話 最速インターフェース研究会 :: タブとスペースと萌ディタの話 404 Blog Not Found:タブのスペース化はタブ幅よりも重要である これはエディタと同じでき...
[misc] タブとスペースの話【ひげぽん OSとか作っちゃうかMona-】at 2006年04月30日 13:15
タブのスペース化はタブ幅よりも重要であるより。 私はスペース派。インデントは C 系の言語 は 4 で、Ruby は 2 で書いてる。 スペース派である理由は、「タブでインデントすると、タブ幅が違う環境で見たとき、ブロックの行頭以外のところが悲惨になるから」。(こんなので...
インデントとタブのはなし【活動日誌】at 2006年04月30日 09:49
タブのスペース化はタブ幅よりも重要である 内容の99%はスルーするとしてperl -i.bak -ple 's{^([ ]+)}{"\t" x (length($1)/4)}e' *.pl でtabifyできるではないか。ちょwwwまったwwwwww Ingy++な自分としては、ここは是非ともModule::Compileを使って解決するべき...
そのタブAcme::Tabifyでよくね?Plaggerでもいいけど【YappoLogs】at 2006年04月30日 05:59
Danさんや、あなたはコンパイル済みのプログラムにパッチをあてるとき、いちいちバイナリエディタで開いてしこしこ手で直すとでも言うおつもりか? 君たちは、patchのことをきれいさぱーり忘れている。 人のコードを直したり、人にコードを直してもらったりしなくてもいい...
Patchというのはいつからテキストの専売特許になったのだ?【Charsbar::Note】at 2006年04月30日 05:22
この記事へのコメント
論理がつながっていないのが奇妙ですな。
それほど空白が好きならdiffをそのままshellからコピペせずファイルにリダイレクトして張り付ければいいじゃん。
そもそもpatchつかってないじゃん?

Posted by しろ at 2009年01月07日 13:40
Tiger氏に同意、プログラムとしての\tと、(プログラムの動作に影響を与えない)インデントとしてのTABは話として別物かと・・・
Posted by narusase at 2008年10月09日 12:32
相手に、というか
開発グループ内で統一された表記を使った方が良いかと思いますが、
そもそもtabとスペースを区別できないソース管理システムを選択するのが
間違いだと思います。
Posted by くまぱんだ at 2006年05月01日 17:28
パッチを送る際は、好きであろうがなかろうが相手のスタイルに合わせるのがマナーだと思いますが。
Posted by foo at 2006年04月30日 22:41
「これをファイルに落とさず、そのままshellからコピペした場合」っては確かにやってしまうけれど、これがそもそもいけないような(笑
まあ、スペースにいろんな意味を多重に載せるのは Perl らしい気もしないではないですが、自由度が高すぎてハンドリングしにくいと感じるのも確かです。
あと、サンプルの中で \t をタブに展開するのと、インデントとしてタブを使うのとを混ぜるのは別に扱うべきと感じましたよ?

という私はスペース派ですが。環境やセッティングに依存しないというメリットがあるので。ただし「一つのソースの中でインデントの段数によってスペース数を変えるということはしない」というルールは自分に課しています。
Posted by Tiger at 2006年04月30日 11:31
いまどきのエディタって「保存時にタブをスペース何個に変換する」みたいなオプションがあるのかな?
Posted by wosio at 2006年04月30日 08:31
GNU Makefileだっけ?
Posted by kosaki at 2006年04月30日 06:31
分離記号を欠いています (8 個の空白でしたが、TAB のつもりですか?

と警告を吐き出す世界もあったりします。
ご参考までに……
Posted by unknown at 2006年04月30日 04:05