タイトルは適当
ネタ元→ 低レイヤの文字列操作 - おさかなラボ
ちょっとC書いてて、あるファイルがWindowsのスクリーンセーバーかどうか拡張子(.scr)で判別するロジックで、拡張子に大文字小文字がことがあることが判明したあと、ものすごくロジック書くのが面倒くさくなってきた俺はイラっときて次のように書いた。char *p = filename + strlen(filename); char lc = 'a' - 'A'; if((*--p|lc) == 'r' && (*--p|lc) == 'c' && (*--p|lc) == 's' && *--p == '.'){ // みつかったよ! }
まぁ、別にコードは間違ってはいないんだろうけど、
/* filename が ".scr" で終わってるかどうかチェックする */
char *p = filename + strlen(filename) - 4; /* 4 は ".scr" の文字列長 */
if ( p > filename && /* filename の文字列長が 4 より多いことのチェック */
p[0] == '.' &&
tolower(p[1]) == 's' &&
tolower(p[2]) == 'c' &&
tolower(p[3]) == 'r' )
{
/* 見つかったよ! */
}
とかの方が読みやすいんじゃないかな。拡張子名判定なんてそんなカリッカリにチューニングするようなもんでもないだろうし。
それにしても、 記事の前後の文脈がわからないので、何で、
Perlに限らずLL書いてる人ってこういう発想はさすがに出てこないんじゃないだろか。
っていうのが出てくるのかよく分からない。 確かにPerlで普通にコード書いてると、文字列をポインタで舐めながら処理するとか出来ないし、上のような処理をしようとしたら、無理矢理
# 低レイヤ風
my @p = unpack("C*", $filename); # filenameを文字単位で分割
my $lc = ord('a') - ord('A');
if ( (pop @p|$lc) == ord('r') && ## 末尾の文字を取り出して
(pop @p|$lc) == ord('c') && ## マスク($lc)とORをとって
(pop @p|$lc) == ord('s') && ## 小文字化してからチェック
pop @p == ord('.') )
{
# 見つかったよ
}
みたいになってしまう。しかし、どう考えても
if ($filename =~ /\.scr$/i) {
# 見つかったよ
}
の方が(Perlだと)普通だし、読みやすい。
うーん、なんだろ。確かに低いレイヤの処理についてある程度の理解があった方がよろしいのは分かるんだが。CならCなりの書き方すればいいし、PerlならPerlなりの書き方すればいいし...
...
...
.. (ピコーン
結論: 読みやすいコードを書こう (ぇ-
# TODO: 何か引用がやたら読みづらいので後で何とかする





コメントする