Schwartzian変換の(悪い)例
@rows = map { $_->[0] } sort { my $cmp; foreach my $i (1 .. @sort_pos) { $cmp = $a->[$i] cmp $b->[$i]; last if $cmp != 0; } $cmp; } map { my @data; foreach my $pos (@sort_pos) { push(@data, $_->[$pos]); } [$_, @data]; } @rows;
信じられないかもしれないけど、これで1つの代入文。ちょっと目を離すと自分でも読めなくなりそうな恐ろしいコードで、もうなにがなにやら(実際のコードはさらにもう少し複雑で、これでも単純化してある)。本当はここでもforeachを使うのは好きじゃない(sortの部分は局所再帰が使えるともっとすっきり書けるし、後半のforeachはmapで書ける)んだけど、これ以上可読性を損なうわけにはいかないので美しさよりも典型的な書き方を優先することにした。
ちなみに、これは複数カラムによるソートを実装した部分で、もしこれが単一のカラムだったらこうなる:
@rows = map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [$_, $_->[$sort_pos]] } @rows;
単純明快。実に分かりやすい。構造的には上と何ら変わらないはずなのに、明らかに理解のしやすさに差があるというのは考えてみると不思議だ。いかに人間がコンパイラのように文法だけ見ているわけではないかということがよく分かる。