From: "H.Yamamoto" Date: 2004-03-30T13:02:59+09:00 Subject: [ruby-dev:23260] Re: File.fnmatch とDir.glob の非互換部分 山本です。 touch a とした後 puts File.fnmatch("a\\", "a") puts File.fnmatch("a\\", "a\\") puts Dir.glob("a\\") を実行すると、 false true a となって、不完全なエスケープの解釈が一貫していません。 File.fnmatch は、不完全なエスケープを通常文字の'\'とみなし、 Dir.glob は、PLAIN な場合の不完全なエスケープを remove_backslashes で削除しています。 どうするのがいいでしょうか?実装しやすいのは、不完全なエスケープを削除するのが一番です。 通常文字として扱うと、'a\/b' を '/' で単に分けたときに 'a\' と 'b' になってしまうので、 '\/' で分けるようにしないといけません。なので、remove_backslashes、glob_make_pattern で それぞれ余分な条件文を追加しなくてはいけません。 不完全なエスケープを削除するだけなら、下のパッチだけですむと思います。'a\/b' を '/' で 分けても、'a\' は 'a' といっしょですから。もちろん、たまたまそうだというだけで、あんまり 感心しないパッチではありますが、そもそも不完全なエスケープは文法エラーなので、それに 対応するために余分なコードを追加しなくてもいいかな、と思います。 Index: dir.c =================================================================== RCS file: /ruby/ruby/dir.c,v retrieving revision 1.113 diff -u -w -b -p -r1.113 dir.c --- dir.c 16 Mar 2004 02:24:47 -0000 1.113 +++ dir.c 30 Mar 2004 03:51:17 -0000 @@ -210,7 +210,7 @@ bracket(p, s, flags) End marker itself won't be compared. And if function succeeds, *pcur reaches end marker. */ -#define UNESCAPE(p) (escape && *(p) == '\\' && (p)[1] ? (p) + 1 : (p)) +#define UNESCAPE(p) (escape && *(p) == '\\' ? (p) + 1 : (p)) #define ISEND(p) (!*(p) || (pathname && *(p) == '/')) #define RETURN(val) return *pcur = p, *scur = s, (val);