diff --git a/ChangeLog b/ChangeLog index 9291152759..fb7026e155 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,10 +1,43 @@ +Thu Jul 3 14:22:46 2003 Yukihiro Matsumoto + + * array.c (rb_values_at): extract common procedure from + rb_ary_values_at. follow DRY principle. + + * re.c (match_values_at): values_at should understand ranges. + + * struct.c (rb_struct_values_at): ditto. + + * struct.c (inspect_struct): inspect format changed; add "struct " + at the top. + + * sprintf.c (rb_f_sprintf): "%p" specifier for inspect output. + (RCR#68) + + * eval.c (rb_mod_undef_method): allow "undef_method" to accept + multiple arguments. (RCR#146) + + * lib/timeout.rb: put timeout in Timeout module. (RCR#121) + [ruby-talk:61028] + + * re.c (match_groups): new method added. (RCR#139) + + * variable.c (rb_mod_const_of): should exclude constant defined + in Object, unless retrieving constants of Object. + Thu Jul 3 12:13:05 2003 WATANABE Hirofumi * lib/mkmf.rb (VPATH): convert from Windows form to Unix form on MinGW. This fixes the build with GNU make 3.80-1 for Cygwin. +Wed Jul 2 23:27:34 2003 Yukihiro Matsumoto + + * string.c (rb_str_new4): do not allocate new string if original + is frozen or already have copy-on-write entry. [ruby-talk:74940] + Wed Jul 2 13:22:39 2003 Yukihiro Matsumoto + * string.c (rb_str_new4): + * string.c (rb_str_shared_replace): clear flags before copy. * string.c (rb_str_replace): ditto. diff --git a/array.c b/array.c index 69bf714e6f..3687772fc3 100644 --- a/array.c +++ b/array.c @@ -1218,29 +1218,37 @@ rb_ary_collect_bang(ary) return ary; } -static void -push_values_at(result, ary, arg) - VALUE result, ary, arg; +VALUE +rb_values_at(obj, olen, argc, argv, func) + VALUE obj; + long olen; + int argc; + VALUE *argv; + VALUE (*func) _((VALUE,long)); { - long beg, len, i; + VALUE result = rb_ary_new2(argc); + long beg, len, i, j; - if (FIXNUM_P(arg)) { - rb_ary_push(result, rb_ary_entry(ary, FIX2LONG(arg))); - return; - } - /* check if idx is Range */ - switch (rb_range_beg_len(arg, &beg, &len, RARRAY(ary)->len, 0)) { - case Qfalse: - break; - case Qnil: - return; - default: - for (i=0; ilen, argc, argv, rb_ary_entry); } static VALUE diff --git a/eval.c b/eval.c index 186e23db95..f560d3a185 100644 --- a/eval.c +++ b/eval.c @@ -362,6 +362,7 @@ rb_get_method_body(klassp, idp, noexp) body = ent->method = body->nd_head; } else { + if (BUILTIN_TYPE(origin) == T_ICLASS) origin = RBASIC(origin)->klass; *klassp = origin; ent->origin = origin; ent->mid = ent->mid0 = id; @@ -1824,10 +1825,16 @@ rb_undef(klass, id) } static VALUE -rb_mod_undef_method(mod, name) - VALUE mod, name; +rb_mod_undef_method(argc, argv, mod) + int argc; + VALUE *argv; + VALUE mod; { - rb_undef(mod, rb_to_id(name)); + int i; + + for (i=0; iregs; VALUE ary = rb_ary_new2(regs->num_regs); @@ -923,7 +924,7 @@ match_to_a(match) int i; int taint = OBJ_TAINTED(match); - for (i=0; inum_regs; i++) { + for (i=start; inum_regs; i++) { if (regs->beg[i] == -1) { rb_ary_push(ary, Qnil); } @@ -936,6 +937,20 @@ match_to_a(match) return ary; } +static VALUE +match_to_a(match) + VALUE match; +{ + return match_array(match, 0); +} + +static VALUE +match_groups(match) + VALUE match; +{ + return match_array(match, 1); +} + static VALUE match_aref(argc, argv, match) int argc; @@ -952,32 +967,21 @@ match_aref(argc, argv, match) return rb_reg_nth_match(FIX2INT(idx), match); } +static VALUE +match_entry(match, n) + VALUE match; + long n; +{ + return rb_reg_nth_match(n, match); +} + static VALUE match_values_at(argc, argv, match) int argc; VALUE *argv; VALUE match; { - struct re_registers *regs = RMATCH(match)->regs; - VALUE target = RMATCH(match)->str; - VALUE result = rb_ary_new(); - int i; - long idx; - int taint = OBJ_TAINTED(match); - - for (i=0; inum_regs; - if (idx < 0 || regs->num_regs <= idx) { - rb_ary_push(result, Qnil); - } - else { - VALUE str = rb_str_substr(target, regs->beg[idx], regs->end[idx]-regs->beg[idx]); - if (taint) OBJ_TAINT(str); - rb_ary_push(result, str); - } - } - return result; + return rb_values_at(match, RMATCH(match)->regs->num_regs, argc, argv, match_entry); } static VALUE @@ -1766,6 +1770,7 @@ Init_Regexp() rb_define_method(rb_cMatch, "end", match_end, 1); rb_define_method(rb_cMatch, "to_a", match_to_a, 0); rb_define_method(rb_cMatch, "[]", match_aref, -1); + rb_define_method(rb_cMatch, "groups", match_groups, 0); rb_define_method(rb_cMatch, "select", match_select, -1); rb_define_method(rb_cMatch, "values_at", match_values_at, -1); rb_define_method(rb_cMatch, "pre_match", rb_reg_match_pre, 0); diff --git a/sprintf.c b/sprintf.c index b89f441708..70bd270f2b 100644 --- a/sprintf.c +++ b/sprintf.c @@ -291,10 +291,12 @@ rb_f_sprintf(argc, argv) break; case 's': + case 'p': { VALUE arg = GETARG(); long len; + if (*p == 'p') arg = rb_inspect(arg); str = rb_obj_as_string(arg); if (OBJ_TAINTED(str)) tainted = 1; len = RSTRING(str)->len; diff --git a/string.c b/string.c index 25b325f0ec..692a158c09 100644 --- a/string.c +++ b/string.c @@ -157,14 +157,17 @@ rb_str_new4(orig) { VALUE klass, str; + if (OBJ_FROZEN(orig)) return orig; klass = rb_obj_class(orig); if (FL_TEST(orig, ELTS_SHARED) && RSTRING(orig)->aux.shared) { long ofs; str = RSTRING(orig)->aux.shared; ofs = RSTRING(str)->len - RSTRING(orig)->len; - str = str_new3(klass, str); - RSTRING(str)->ptr += ofs; - RSTRING(str)->len -= ofs; + if (ofs > 0) { + str = str_new3(klass, str); + RSTRING(str)->ptr += ofs; + RSTRING(str)->len -= ofs; + } } else if (FL_TEST(orig, STR_ASSOC)) { str = str_new(klass, RSTRING(orig)->ptr, RSTRING(orig)->len); diff --git a/struct.c b/struct.c index 6d9c8113a9..32ea8f525c 100644 --- a/struct.c +++ b/struct.c @@ -351,18 +351,6 @@ rb_struct_each_pair(s) return s; } -static VALUE -rb_struct_to_s(s) - VALUE s; -{ - char *cname = rb_class2name(rb_obj_class(s)); - VALUE str = rb_str_new(0, strlen(cname) + 4); - - sprintf(RSTRING(str)->ptr, "#<%s>", cname); - RSTRING(str)->len = strlen(RSTRING(str)->ptr); - return str; -} - static VALUE inspect_struct(s) VALUE s; @@ -376,7 +364,7 @@ inspect_struct(s) rb_bug("non-initialized struct"); } - str = rb_str_buf_new2("#<"); + str = rb_str_buf_new2("#len; i++) { @@ -405,9 +393,9 @@ rb_struct_inspect(s) { if (rb_inspecting_p(s)) { char *cname = rb_class2name(rb_obj_class(s)); - VALUE str = rb_str_new(0, strlen(cname) + 8); + VALUE str = rb_str_new(0, strlen(cname) + 15); - sprintf(RSTRING(str)->ptr, "#<%s:...>", cname); + sprintf(RSTRING(str)->ptr, "#", cname); RSTRING(str)->len = strlen(RSTRING(str)->ptr); return str; } @@ -529,20 +517,21 @@ rb_struct_aset(s, idx, val) return RSTRUCT(s)->ptr[i] = val; } +static VALUE +struct_entry(s, n) + VALUE s; + long n; +{ + return rb_struct_aref(s, LONG2NUM(n)); +} + static VALUE rb_struct_values_at(argc, argv, s) int argc; VALUE *argv; VALUE s; { - VALUE result = rb_ary_new(); - long i; - - for (i=0; ilen, argc, argv, struct_entry); } static VALUE @@ -648,7 +637,7 @@ Init_Struct() rb_define_method(rb_cStruct, "eql?", rb_struct_eql, 1); rb_define_method(rb_cStruct, "hash", rb_struct_hash, 0); - rb_define_method(rb_cStruct, "to_s", rb_struct_to_s, 0); + rb_define_method(rb_cStruct, "to_s", rb_struct_inspect, 0); rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0); rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0); rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0); diff --git a/variable.c b/variable.c index fcbc8cc745..8b62aad92a 100644 --- a/variable.c +++ b/variable.c @@ -1387,10 +1387,12 @@ rb_mod_const_of(mod, data) VALUE mod; void *data; { + VALUE tmp = mod; for (;;) { - data = rb_mod_const_at(mod, data); - mod = RCLASS(mod)->super; - if (!mod) break; + data = rb_mod_const_at(tmp, data); + tmp = RCLASS(tmp)->super; + if (!tmp) break; + if (tmp == rb_cObject && mod != rb_cObject) break; } return data; }