山本です。

>できればユニットテストを用意して、これとこれと
>このテストケースが失敗するようになります、しかし次のような
>利点があります……。と言ってくれればベストです。

用意してみます。

>なぜ反対かと言えば、ぼくは fnmatch という名前からは fnmatch(3)
>しか想像できないからです。また、SUSv3 に準拠するならするで、
>ぜんぶ準拠すべきだと思います。

>File.fnmatch の仕様が使いにくいからもっと使いやすいメソッドが
>欲しい、というのであれば、他のメソッドを作って解決したほうが
>よいと思います。例えば File.glob_match?(pat, str) とか。

その方がいいですね、きっと。ところで、
File.fnmatch に FNM_PERIOD を復活させると互換性の問題が生じるのですが、
これはいいのでしょうか?

>わたしが ruby-devも含めて見た限り、まず fnmatch の実装を高速化することが第一義
>で、残りはその実装の過程で都合のいいように仕様を改変したように
>しか見えません。

いえ、それは違います。もともと fnmatch に目を向けたきっかけは、Dir.glob は '[' より '/' の区切りを優先させて
いるのに、File.fnmatch は '[' を優先させているので、一貫性がないという仕様上の問題でした。[ruby-dev:22862]
(結果的に '*' の処理が高速化しましたが、それはたまたまです)

その後、私は File.fnmatch でも '[' より '/' を優先すべきではないか、と主張しましたが、
それは実装の都合ではなく、FNM_PATHNAME がある、つまりパス単位ごとの処理なのに、
'[ ]' に '/' を含むという仕様にどうしても違和感を感じたからです。
SUSv3 の仕様を知って正直嬉しかったのは認めます。

>そして、だからこそわけのわからない主張になるし、
>他の人も意見の言いようがないのではないでしょうか。

うーん、そうだったんですか?

>そもそも「改良」というからには悪いところを直すのでなければ
>なりません。ならば、まずどこがどのように悪いのかを指摘すべきです。

第一に、DOSISH の問題です。

E:\ruby-cvs>miniruby_1_8 -e "puts File.fnmatch('hoge\[abc]', 'hoge\a')"
false

これは、\ がパス区切りとしての働きより、'[' のエスケープとしての働きを優先しているからで、
直感と異なります。この辺りがHEADでは複雑だったので、私の実装では '/' だけとしました。
ですが、パターンで '\' をパス区切りとして使わなければいいので、マッチされる文字列では
'\' を使えるようにはできます。

第二に、'*' の処理速度です。

File.fnmatch('e*c', 'eeee') といったマッチのとき、

  1番目が 'e' である (OK)
  2番目が 'c' でない
  3番目が 'c' でない
  4番目が 'c' でない

でマッチしないことは確定するのですが、HEADの実装では

  2番目が 'e' である (OK)
  3番目が 'c' でない
  ・・・

と、位置をずらしてマッチしなおしていたので、処理が遅くなっていました。この点が改善されています。

第三に、SUSv3 準拠でない点です。

  % dir {pattern}

とした同じパターンで

  % ruby -e "Dir.glob({pattern}){|path| .... }"

とできるのは利点だと思います。また、今のパターンは、ruby の正規表現に近いものになってますが、
どのみち正規表現のような /[^.]*\.html/ といった柔軟な処理はできないので、SUSv3 のパターンマッチに
準拠した方が混乱が少ないと思います。