At Fri, 8 Mar 2002 17:31:15 +0900,
matz wrote:
> 「Dir::[]の第2引数はあんまりよくないのでは」というのは、どう
> しますか? 個人的には複数パターンを受け付ける必要はないと思っ
> てはいますが、ここの引数はなるたけ対等であって欲しいのですが。

 現行の [] と glob が等価というのを踏襲しただけで、私としては
どちらでもいいと思っていました。

 確かに Dir["*", File::FNM_DOTMATCH] というのは気持ち悪いので、
Dir[] はフラグを受け付けないようにしたいと思います。

> で、Dir::globおよびその他の変更については反対しません。

 ありがとうございます。

-- 
                     /
                    /__  __            Akinori.org / MUSHA.org
                   / )  )  ) )  /     FreeBSD.org / Ruby-lang.org
Akinori MUSHA aka / (_ /  ( (__(  @ iDaemons.org / and.or.jp

"Somewhere out of a memory.. of lighted streets on quiet nights.."

Index: dir.c
===================================================================
RCS file: /src/ruby/dir.c,v
retrieving revision 1.60
diff -u -u -r1.60 dir.c
--- dir.c	2002/02/18 09:52:45	1.60
+++ dir.c	2002/03/08 10:10:26
@@ -69,7 +69,7 @@
 
 #define FNM_NOESCAPE	0x01
 #define FNM_PATHNAME	0x02
-#define FNM_PERIOD	0x04
+#define FNM_DOTMATCH	0x04
 #define FNM_CASEFOLD	0x08
 
 #define FNM_NOMATCH	1
@@ -153,7 +153,7 @@
     const char *s = string;
     int escape = !(flags & FNM_NOESCAPE);
     int pathname = flags & FNM_PATHNAME;
-    int period = flags & FNM_PERIOD;
+    int period = !(flags & FNM_DOTMATCH);
     int nocase = flags & FNM_CASEFOLD;
 
     while (c = *pat++) {
@@ -188,7 +188,7 @@
 	    pat--;
 	    while (*s) {
 		if ((c == '[' || downcase(*s) == test) &&
-		    !fnmatch(pat, s, flags & ~FNM_PERIOD))
+		    !fnmatch(pat, s, flags | FNM_DOTMATCH))
 		    return 0;
 		else if (ISDIRSEP(*s))
 		    break;
@@ -793,13 +793,23 @@
     }
 }
 
+static void
+rb_glob2(path, flags, func, arg)
+    char *path;
+    int flags;
+    void (*func) _((const char*, VALUE));
+    VALUE arg;
+{
+    glob_helper(path, 0, flags, func, arg);
+}
+
 void
 rb_glob(path, func, arg)
     char *path;
     void (*func) _((const char*, VALUE));
     VALUE arg;
 {
-    glob_helper(path, 0, FNM_PERIOD, func, arg);
+    rb_glob2(path, 0, func, arg);
 }
 
 void
@@ -808,11 +818,9 @@
     void (*func) _((const char*, VALUE));
     VALUE arg;
 {
-    glob_helper(path, 0, FNM_PERIOD|FNM_CASEFOLD, func, arg);
+    rb_glob2(path, FNM_CASEFOLD, func, arg);
 }
 
-static void push_pattern _((const char *path, VALUE ary));
-
 static void
 push_pattern(path, ary)
     const char *path;
@@ -829,17 +837,19 @@
 }
 
 static void
-push_globs(ary, s)
+push_globs(ary, s, flags)
     VALUE ary;
     char *s;
+    int flags;
 {
-    rb_glob(s, push_pattern, ary);
+    rb_glob2(s, flags, push_pattern, ary);
 }
 
 static void
-push_braces(ary, s)
+push_braces(ary, s, flags)
     VALUE ary;
     char *s;
+    int flags;
 {
     char *buf;
     char *p, *t, *b;
@@ -878,31 +888,35 @@
 	    }
 	    memcpy(b, t, p-t);
 	    strcpy(b+(p-t), rbrace+1);
-	    push_braces(ary, buf);
+	    push_braces(ary, buf, flags);
 	}
 	free(buf);
     }
     else {
-	push_globs(ary, s);
+	push_globs(ary, s, flags);
     }
 }
 
 #define isdelim(c) ((c)=='\0')
 
 static VALUE
-dir_s_glob(dir, str)
-    VALUE dir, str;
+rb_push_glob(str, flags)
+    VALUE str;
+    int flags;
 {
     char *p, *pend;
     char *buf;
     char *t;
-    int nest;
-    VALUE ary = 0;
+    int nest, maxnest;
+    int noescape = flags & FNM_NOESCAPE;
+    VALUE ary;
 
-    SafeStringValue(str);
-    if (!rb_block_given_p()) {
+    if (rb_block_given_p())
+	ary = Qnil;
+    else
 	ary = rb_ary_new();
-    }
+
+    SafeStringValue(str);
     buf = xmalloc(RSTRING(str)->len + 1);
 
     p = RSTRING(str)->ptr;
@@ -913,28 +927,50 @@
 	nest = 0;
 	while (p < pend && isdelim(*p)) p++;
 	while (p < pend && !isdelim(*p)) {
-	    if (*p == '{') nest+=2;
-	    if (*p == '}') nest+=3;
-	    if (*p == '\\') {
+	    if (*p == '{') nest++, maxnest++;
+	    if (*p == '}') nest--;
+	    if (!noescape && *p == '\\') {
 		*t++ = *p++;
 		if (p == pend) break;
 	    }
 	    *t++ = *p++;
 	}
 	*t = '\0';
-	if (nest == 0) {
-	    push_globs(ary, buf);
+	if (maxnest == 0) {
+	    push_globs(ary, buf, flags);
 	}
-	else if (nest % 5 == 0) {
-	    push_braces(ary, buf);
+	else if (nest == 0) {
+	    push_braces(ary, buf, flags);
 	}
 	/* else unmatched braces */
     }
     free(buf);
-    if (ary) {
-	return ary;
-    }
-    return Qnil;
+
+    return ary;
+}
+
+static VALUE
+dir_s_aref(obj, str)
+    VALUE obj, str;
+{
+    return rb_push_glob(str, 0);
+}
+
+static VALUE
+dir_s_glob(argc, argv, obj)
+    int argc;
+    VALUE *argv;
+    VALUE obj;
+{
+    VALUE str, rflags;
+    int flags;
+
+    if (rb_scan_args(argc, argv, "11", &str, &rflags) == 2)
+	flags = NUM2INT(rflags);
+    else
+	flags = 0;
+
+    return rb_push_glob(str, flags);
 }
 
 static VALUE
@@ -1014,14 +1050,14 @@
     rb_define_singleton_method(rb_cDir,"delete", dir_s_rmdir, 1);
     rb_define_singleton_method(rb_cDir,"unlink", dir_s_rmdir, 1);
 
-    rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, 1);
-    rb_define_singleton_method(rb_cDir,"[]", dir_s_glob, 1);
+    rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, -1);
+    rb_define_singleton_method(rb_cDir,"[]", dir_s_aref, 1);
 
     rb_define_singleton_method(rb_cFile,"fnmatch", file_s_fnmatch, -1);
     rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1);
 
     rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE));
     rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME));
-    rb_file_const("FNM_PERIOD", INT2FIX(FNM_PERIOD));
+    rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH));
     rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD));
 }