summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-12-11 03:48:08 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2001-12-11 03:48:08 +0000
commita59c599209a11d4ab0dc0d7626ab3d5ca43a78c2 (patch)
treef4c4400099a7feb51a7b303cbedc0e1f04714f43
parent8a91c99905c1bfbf441ec890161538acc8e34120 (diff)
* string.c (rb_str_match_m): should convert an argument into
regexp if it's a string. * array.c (rb_ary_select): Array#select(n,m,...) now works like Array#indexes(n,m,..). [new, experimental] * hash.c (rb_hash_select): ditto. * hash.c (env_select): ditto. * re.c (match_select): ditto. * struct.c (rb_struct_select): ditto. * gc.c (STR_ASSOC): use FL_USER3 instead of FL_USER2. * parse.y (str_extend): make up pushback call. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1905 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog26
-rw-r--r--ToDo2
-rw-r--r--array.c30
-rw-r--r--gc.c2
-rw-r--r--hash.c78
-rw-r--r--parse.y1
-rw-r--r--re.c29
-rw-r--r--string.c7
-rw-r--r--struct.c29
-rw-r--r--variable.c5
10 files changed, 203 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index ad40b36444..d1fc61e1cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+Tue Dec 11 12:45:28 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * string.c (rb_str_match_m): should convert an argument into
+ regexp if it's a string.
+
+Tue Dec 11 03:40:23 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_select): Array#select(n,m,...) now works like
+ Array#indexes(n,m,..). [new, experimental]
+
+ * hash.c (rb_hash_select): ditto.
+
+ * hash.c (env_select): ditto.
+
+ * re.c (match_select): ditto.
+
+ * struct.c (rb_struct_select): ditto.
+
Tue Dec 11 03:17:19 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* object.c (rb_class_real): follow included modules.
@@ -7,6 +25,14 @@ Mon Dec 10 23:37:51 2001 Usaku Nakamura <usa@ruby-lang.org>
* util.h: change prototype of ruby_qsort() to accord with its
definition.
+Mon Dec 10 20:30:01 2001 K.Kosako <kosako@sofnec.co.jp>
+
+ * gc.c (STR_ASSOC): use FL_USER3 instead of FL_USER2.
+
+Mon Dec 10 17:40:02 2001 K.Kosako <kosako@sofnec.co.jp>
+
+ * parse.y (str_extend): make up pushback call.
+
Mon Dec 10 02:09:28 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* array.c (rb_ary_modify): should copy the internal buffer if the
diff --git a/ToDo b/ToDo
index 4c826c0528..0f9b3f1b06 100644
--- a/ToDo
+++ b/ToDo
@@ -74,6 +74,7 @@ Standard Libraries
- Integer#to_s(base)
- Hash::new{default}
- hash etc. should handle self referenceing array/hash
+- Array#select(n1,n2...) works like Array#indexes(n1,n2...)
* String#scanf(?)
* Object#fmt(?)
* Time::strptime
@@ -96,7 +97,6 @@ Standard Libraries
* new caller(), e.g. call_stack; needs better name.
* remove dependency on MAXPATHLEN.
* pointer share mechanism similar to one in String for Array.
-* Array#select(n1,n2...) works like Array#indexes(n1,n2...)
* deprecate Array#indexes, and Array#indices.
Extension Libraries
diff --git a/array.c b/array.c
index 0401dd3598..c9b66eb2ed 100644
--- a/array.c
+++ b/array.c
@@ -590,6 +590,8 @@ rb_ary_indexes(argc, argv, ary)
VALUE new_ary;
long i;
+ rb_warn("Array#%s is deprecated; use Array#select",
+ rb_id2name(rb_frame_last_func()));
new_ary = rb_ary_new2(argc);
for (i=0; i<argc; i++) {
rb_ary_push(new_ary, rb_ary_aref(1, argv+i, ary));
@@ -1171,6 +1173,33 @@ rb_ary_filter(ary)
return rb_ary_collect_bang(ary);
}
+static VALUE
+rb_ary_select(argc, argv, ary)
+ int argc;
+ VALUE *argv;
+ VALUE ary;
+{
+ VALUE result = rb_ary_new();
+ long i;
+
+ if (rb_block_given_p()) {
+ if (argc > 0) {
+ rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
+ }
+ for (i = 0; i < RARRAY(ary)->len; i++) {
+ if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
+ rb_ary_push(result, RARRAY(ary)->ptr[i]);
+ }
+ }
+ }
+ else {
+ for (i=0; i<argc; i++) {
+ rb_ary_push(result, rb_ary_entry(ary, NUM2LONG(argv[i])));
+ }
+ }
+ return result;
+}
+
VALUE
rb_ary_delete(ary, item)
VALUE ary;
@@ -1837,6 +1866,7 @@ Init_Array()
rb_define_method(rb_cArray, "sort!", rb_ary_sort_bang, 0);
rb_define_method(rb_cArray, "collect", rb_ary_collect, 0);
rb_define_method(rb_cArray, "collect!", rb_ary_collect_bang, 0);
+ rb_define_method(rb_cArray, "select", rb_ary_select, -1);
rb_define_method(rb_cArray, "map", rb_ary_collect, 0);
rb_define_method(rb_cArray, "map!", rb_ary_collect_bang, 0);
rb_define_method(rb_cArray, "filter", rb_ary_filter, 0);
diff --git a/gc.c b/gc.c
index 4b72db951d..573a6e34f9 100644
--- a/gc.c
+++ b/gc.c
@@ -766,7 +766,7 @@ rb_gc_mark_children(ptr)
break;
case T_STRING:
-#define STR_ASSOC FL_USER2 /* copied from string.c */
+#define STR_ASSOC FL_USER3 /* copied from string.c */
if (FL_TEST(obj, ELTS_SHARED|STR_ASSOC)) {
rb_gc_mark(obj->as.string.aux.shared);
}
diff --git a/hash.c b/hash.c
index 94c7e33a33..b91ce7f113 100644
--- a/hash.c
+++ b/hash.c
@@ -385,6 +385,8 @@ rb_hash_indexes(argc, argv, hash)
VALUE indexes;
int i;
+ rb_warn("Hash#%s is deprecated; use Hash#select",
+ rb_id2name(rb_frame_last_func()));
indexes = rb_ary_new2(argc);
for (i=0; i<argc; i++) {
RARRAY(indexes)->ptr[i] = rb_hash_aref(hash, argv[i]);
@@ -484,6 +486,42 @@ rb_hash_reject(hash)
}
static int
+select_i(key, value, result)
+ VALUE key, value;
+{
+ VALUE assoc;
+
+ if (key == Qundef) return ST_CONTINUE;
+ assoc = rb_assoc_new(key, value);
+ if (RTEST(rb_yield(assoc)))
+ rb_ary_push(result, assoc);
+ return ST_CONTINUE;
+}
+
+VALUE
+rb_hash_select(argc, argv, hash)
+ int argc;
+ VALUE *argv;
+ VALUE hash;
+{
+ VALUE result = rb_ary_new();
+ long i;
+
+ if (rb_block_given_p()) {
+ if (argc > 0) {
+ rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
+ }
+ rb_hash_foreach(hash, select_i, result);
+ }
+ else {
+ for (i=0; i<argc; i++) {
+ rb_ary_push(result, rb_hash_aref(hash, argv[i]));
+ }
+ }
+ return result;
+}
+
+static int
clear_i(key, value, dummy)
VALUE key, value, dummy;
{
@@ -1253,6 +1291,42 @@ env_delete_if()
}
static VALUE
+env_select(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE result = rb_ary_new();
+ long i;
+
+ if (rb_block_given_p()) {
+ char **env;
+
+ if (argc > 0) {
+ rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
+ }
+ env = GET_ENVIRON(environ);
+ while (*env) {
+ char *s = strchr(*env, '=');
+ if (s) {
+ VALUE str = rb_tainted_str_new(*env, s-*env);
+
+ if (RTEST(rb_yield(str))) {
+ rb_ary_push(result, str);
+ }
+ }
+ env++;
+ }
+ FREE_ENVIRON(environ);
+ }
+ else {
+ for (i=0; i<argc; i++) {
+ rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
+ }
+ }
+ return result;
+}
+
+static VALUE
env_to_s()
{
return rb_str_new2("ENV");
@@ -1407,6 +1481,8 @@ env_indexes(argc, argv)
int i;
VALUE indexes = rb_ary_new2(argc);
+ rb_warn("ENV.%s is deprecated; use ENV.select",
+ rb_id2name(rb_frame_last_func()));
for (i=0;i<argc;i++) {
char *v = 0;
if (TYPE(argv[i]) == T_STRING) {
@@ -1498,6 +1574,7 @@ Init_Hash()
rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
+ rb_define_method(rb_cHash,"select", rb_hash_select, -1);
rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
@@ -1529,6 +1606,7 @@ Init_Hash()
rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
rb_define_singleton_method(envtbl,"reject", env_reject, 0);
rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
+ rb_define_singleton_method(envtbl,"select", env_select, -1);
rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
rb_define_singleton_method(envtbl,"rehash", env_none, 0);
diff --git a/parse.y b/parse.y
index 96a7fd6edd..067775edfb 100644
--- a/parse.y
+++ b/parse.y
@@ -3960,6 +3960,7 @@ str_extend(list, term, paren)
goto refetch;
}
if (!is_identchar(c)) {
+ pushback(c);
invalid_interporate:
{
VALUE s = rb_str_new2("#");
diff --git a/re.c b/re.c
index f2e2dee4dc..176c3bc8ec 100644
--- a/re.c
+++ b/re.c
@@ -785,7 +785,7 @@ match_to_a(match)
for (i=0; i<regs->num_regs; i++) {
if (regs->beg[i] == -1) rb_ary_push(ary, Qnil);
else rb_ary_push(ary, rb_str_new(ptr+regs->beg[i],
- regs->end[i]-regs->beg[i]));
+ regs->end[i]-regs->beg[i]));
}
return ary;
}
@@ -807,6 +807,32 @@ match_aref(argc, argv, match)
}
static VALUE
+match_select(argc, argv, match)
+ int argc;
+ VALUE *argv;
+ VALUE match;
+{
+ struct re_registers *regs = RMATCH(match)->regs;
+ char *ptr = RSTRING(RMATCH(match)->str)->ptr;
+ VALUE result = rb_ary_new();
+ int i;
+ long idx;
+
+ for (i=0; i<argc; i++) {
+ idx = NUM2LONG(argv[i]);
+ if (idx < 0) idx += regs->num_regs;
+ if (idx < 0 || regs->num_regs <= idx) {
+ rb_ary_push(result, Qnil);
+ }
+ else {
+ rb_ary_push(result, rb_str_new(ptr+regs->beg[idx],
+ regs->end[idx]-regs->beg[idx]));
+ }
+ }
+ return result;
+}
+
+static VALUE
match_to_s(match)
VALUE match;
{
@@ -1436,6 +1462,7 @@ Init_Regexp()
rb_define_method(rb_cMatch, "to_a", match_to_a, 0);
rb_define_method(rb_cMatch, "to_ary", match_to_a, 0);
rb_define_method(rb_cMatch, "[]", match_aref, -1);
+ rb_define_method(rb_cMatch, "select", match_select, -1);
rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0);
rb_define_method(rb_cMatch, "post_match", rb_reg_match_post, 0);
rb_define_method(rb_cMatch, "to_s", match_to_s, 0);
diff --git a/string.c b/string.c
index f3520813a0..640cf7f6de 100644
--- a/string.c
+++ b/string.c
@@ -812,6 +812,7 @@ static VALUE
rb_str_match2(str)
VALUE str;
{
+ StringValue(str);
return rb_reg_match2(rb_reg_regcomp(str));
}
@@ -819,6 +820,12 @@ static VALUE
rb_str_match_m(str, re)
VALUE str, re;
{
+ VALUE str2 = rb_check_convert_type(re, T_STRING, "String", "to_str");
+
+ if (!NIL_P(str2)) {
+ StringValue(re);
+ re = rb_reg_regcomp(re);
+ }
return rb_funcall(re, rb_intern("match"), 1, str);
}
diff --git a/struct.c b/struct.c
index cfc144757e..21043cba99 100644
--- a/struct.c
+++ b/struct.c
@@ -507,6 +507,34 @@ rb_struct_aset(s, idx, val)
return RSTRUCT(s)->ptr[i] = val;
}
+
+static VALUE
+rb_struct_select(argc, argv, s)
+ int argc;
+ VALUE *argv;
+ VALUE s;
+{
+ VALUE result = rb_ary_new();
+ long i;
+
+ if (rb_block_given_p()) {
+ if (argc > 0) {
+ rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc);
+ }
+ for (i = 0; i < RSTRUCT(s)->len; i++) {
+ if (RTEST(rb_yield(RARRAY(s)->ptr[i]))) {
+ rb_ary_push(result, RSTRUCT(s)->ptr[i]);
+ }
+ }
+ }
+ else {
+ for (i=0; i<argc; i++) {
+ rb_ary_push(result, rb_struct_aref(s, argv[i]));
+ }
+ }
+ return result;
+}
+
static VALUE
rb_struct_equal(s, s2)
VALUE s, s2;
@@ -556,6 +584,7 @@ Init_Struct()
rb_define_method(rb_cStruct, "each", rb_struct_each, 0);
rb_define_method(rb_cStruct, "[]", rb_struct_aref, 1);
rb_define_method(rb_cStruct, "[]=", rb_struct_aset, 2);
+ rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
rb_define_method(rb_cStruct, "members", rb_struct_members, 0);
}
diff --git a/variable.c b/variable.c
index 1f8f2fb7ff..7c010a3789 100644
--- a/variable.c
+++ b/variable.c
@@ -143,9 +143,8 @@ classname(klass)
ID classpath = rb_intern("__classpath__");
if (!klass) klass = rb_cObject;
- if (!ROBJECT(klass)->iv_tbl)
- ROBJECT(klass)->iv_tbl = st_init_numtable();
- else if (!st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) {
+ if (ROBJECT(klass)->iv_tbl &&
+ !st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) {
ID classid = rb_intern("__classid__");
if (st_lookup(ROBJECT(klass)->iv_tbl, classid, &path)) {