diff --git a/ChangeLog b/ChangeLog index 88c239efc2..2d8a105211 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,79 @@ +Mon Nov 27 17:00:35 2000 Yukihiro Matsumoto + + * eval.c (rb_eval): should not redefine builtin classes/modules + from within wrapped load. + +Mon Nov 27 08:57:33 2000 Yukihiro Matsumoto + + * eval.c (call_end_proc): should be isolated from outer block. + +Mon Nov 27 00:10:08 2000 Yukihiro Matsumoto + + * io.c (rb_io_ctl): call ioctl/fcntl for fptr->f2 too. + + * process.c (rb_f_fork): call rb_thread_atfork() after creating + child process. + + * eval.c (rb_thread_atfork): kill all other threads immediately, + then turn the current thread into the main thread. + +Sat Nov 25 23:12:22 2000 Yukihiro Matsumoto + + * eval.c (ruby_run): move calling point of rb_trap_exit after + cleaning up threads. + + * eval.c (ruby_finalize): new function to call EXIT trap, END + procs and GC finalizers. + + * eval.c (rb_exec_end_proc): prevent recursion. + + * gc.c (rb_gc_call_finalizer_at_exit): ditto. + + * signal.c (rb_trap_exit): ditto. made static. + + * process.c (rb_f_fork): should swallow all exceptions from block + execution. + + * process.c (fork_rescue): should call ruby_finalize(). + + * parse.y (yycompile): rb_gc() removed. I don't remember why I put + this here. test code? + +Fri Nov 24 22:03:48 2000 Yukihiro Matsumoto + + * range.c (EXCL): exclusive infomation is now stored in an + instance variable. this enables proper marshal dump. + + * process.c (proc_waitpid): should clear rb_last_status ($?) if + no pid was given by waitpid(2). + +Thu Nov 23 01:35:38 2000 Yukihiro Matsumoto + + * process.c (proc_waitpid2): returns nil if no pid found. + +Wed Nov 22 23:45:15 2000 Yukihiro Matsumoto + + * range.c (range_eq): new method. Compares start and end of range + respectively. + +Wed Nov 22 11:01:32 2000 Yukihiro Matsumoto + + * variable.c (rb_mod_class_variables): should honor singleton + class variable rule defined yesterday. + +Tue Nov 21 23:24:14 2000 Mitsuteru S Nakao + + * numeric.c (flodivmod): missing second operand (typo). + Tue Nov 21 03:39:41 2000 Yukihiro Matsumoto + * marshal.c (marshal_load): marshal format compatibility check + revised. greater minor revision is UPWARD compatibile; + downward compatibility is not assured. + * eval.c (is_defined): clarify class variable behavior for - singleton classes. + singleton classes. class variables within singleton class + should be treated like within singleton method. Mon Nov 20 13:45:21 2000 Yukihiro Matsumoto diff --git a/config.sub b/config.sub index 5a8f983c3a..1000343616 100644 --- a/config.sub +++ b/config.sub @@ -989,7 +989,7 @@ case $os in -xenix) os=-xenix ;; - -*mint | -*MiNT) + -mint* | -MiNT*) os=-mint ;; -uxpds) diff --git a/eval.c b/eval.c index 6d300b6244..409da83c32 100644 --- a/eval.c +++ b/eval.c @@ -1114,6 +1114,39 @@ ruby_options(argc, argv) } } +static void rb_exec_end_proc _((void)); + +void +ruby_finalize() +{ + rb_trap_exit(); + rb_exec_end_proc(); + rb_gc_call_finalizer_at_exit(); +} + +void +ruby_stop(ex) + int ex; +{ + int state; + + PUSH_TAG(PROT_NONE); + PUSH_ITER(ITER_NOT); + if ((state = EXEC_TAG()) == 0) { + rb_thread_cleanup(); + rb_thread_wait_other_threads(); + } + else if (ex == 0) { + ex = state; + } + POP_ITER(); + POP_TAG(); + + ex = error_handle(ex); + ruby_finalize(); + exit(ex); +} + void ruby_run() { @@ -1133,23 +1166,7 @@ ruby_run() POP_TAG(); if (state && !ex) ex = state; - PUSH_TAG(PROT_NONE); - PUSH_ITER(ITER_NOT); - if ((state = EXEC_TAG()) == 0) { - rb_trap_exit(); - rb_thread_cleanup(); - rb_thread_wait_other_threads(); - } - else { - ex = state; - } - POP_ITER(); - POP_TAG(); - - ex = error_handle(ex); - rb_exec_end_proc(); - rb_gc_call_finalizer_at_exit(); - exit(ex); + ruby_stop(ex); } static void @@ -2955,17 +2972,12 @@ rb_eval(self, n) } klass = 0; - if ((ruby_class == rb_cObject || ruby_class == ruby_wrapper) && - rb_autoload_defined(node->nd_cname)) { + if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) { rb_autoload_load(node->nd_cname); } if (rb_const_defined_at(ruby_class, node->nd_cname)) { klass = rb_const_get(ruby_class, node->nd_cname); } - if (!klass && ruby_class == ruby_wrapper && - rb_const_defined_at(rb_cObject, node->nd_cname)) { - klass = rb_const_get(rb_cObject, node->nd_cname); - } if (klass) { if (TYPE(klass) != T_CLASS) { rb_raise(rb_eTypeError, "%s is not a class", @@ -3013,17 +3025,12 @@ rb_eval(self, n) rb_raise(rb_eTypeError, "no outer class/module"); } module = 0; - if ((ruby_class == rb_cObject || ruby_class == ruby_wrapper) && - rb_autoload_defined(node->nd_cname)) { + if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) { rb_autoload_load(node->nd_cname); } if (rb_const_defined_at(ruby_class, node->nd_cname)) { module = rb_const_get(ruby_class, node->nd_cname); } - if (!module && ruby_class == ruby_wrapper && - rb_const_defined_at(rb_cObject, node->nd_cname)) { - module = rb_const_get(rb_cObject, node->nd_cname); - } if (module) { if (TYPE(module) != T_MODULE) { rb_raise(rb_eTypeError, "%s is not a module", @@ -3208,11 +3215,14 @@ rb_exit(status) int status; { if (prot_tag) { + VALUE exit; + exit_status = status; - rb_exc_raise(rb_exc_new(rb_eSystemExit, 0, 0)); + exit = rb_exc_new(rb_eSystemExit, 0, 0); + rb_iv_set(exit, "status", INT2NUM(status)); + rb_exc_raise(exit); } - rb_exec_end_proc(); - rb_gc_call_finalizer_at_exit(); + ruby_finalize(); exit(status); } @@ -5602,7 +5612,11 @@ static void call_end_proc(data) VALUE data; { + PUSH_ITER(ITER_NOT); + PUSH_FRAME(); proc_call(data, Qundef); + POP_FRAME(); + POP_ITER(); } static void @@ -5625,24 +5639,28 @@ rb_f_at_exit() return proc; } -void +static void rb_exec_end_proc() { struct end_proc_data *link; int status; - link = end_procs; - while (link) { + while (end_procs) { + link = end_procs; + end_procs = link->next; rb_protect((VALUE(*)())link->func, link->data, &status); if (status) { error_handle(status); } - link = link->next; + free(link); } while (ephemeral_end_procs) { link = ephemeral_end_procs; ephemeral_end_procs = link->next; rb_protect((VALUE(*)())link->func, link->data, &status); + if (status) { + error_handle(status); + } free(link); } } @@ -6915,6 +6933,7 @@ rb_thread_remove(th) rb_thread_t th; { if (th->status == THREAD_KILLED) return; + rb_thread_ready(th); th->status = THREAD_KILLED; th->prev->next = th->next; @@ -7816,6 +7835,7 @@ rb_thread_start_0(fn, arg, th_arg) } POP_TAG(); status = th->status; + if (th == main_thread) ruby_stop(state); rb_thread_remove(th); if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) { th->flags |= THREAD_RAISED; @@ -8214,6 +8234,23 @@ rb_thread_inspect(thread) return str; } +void +rb_thread_atfork() +{ + rb_thread_t th; + + if (rb_thread_alone()) return; + FOREACH_THREAD(th) { + if (th != curr_thread) { + th->status = THREAD_KILLED; + } + } + END_FOREACH(th); + main_thread = curr_thread; + curr_thread->next = curr_thread; + curr_thread->prev = curr_thread; +} + static VALUE rb_cCont; static VALUE diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index e5c2c2ece0..a088d5c493 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -485,6 +485,56 @@ module TkCore end end + def after_idle(cmd=Proc.new) + myid = _curr_cmd_id + cmdid = install_cmd(cmd) + tk_call('after','idle',cmdid) + end + + def clock_clicks(ms=nil) + if ms + tk_call('clock','clicks','-milliseconds').to_i + else + tk_call('clock','clicks').to_i + end + end + + def clock_format(clk, form=nil) + if form + tk_call('clock','format',clk,'-format',form).to_i + else + tk_call('clock','format',clk).to_i + end + end + + def clock_formatGMT(clk, form=nil) + if form + tk_call('clock','format',clk,'-format',form,'-gmt','1').to_i + else + tk_call('clock','format',clk,'-gmt','1').to_i + end + end + + def clock_scan(str, base=nil) + if base + tk_call('clock','scan',str,'-base',base).to_i + else + tk_call('clock','scan',str).to_i + end + end + + def clock_scanGMT(str, base=nil) + if base + tk_call('clock','scan',str,'-base',base,'-gmt','1').to_i + else + tk_call('clock','scan',str,'-gmt','1').to_i + end + end + + def clock_seconds + tk_call('clock','seconds').to_i + end + def TkCore.callback(arg) arg = Array(tk_split_list(arg)) _get_eval_string(TkUtil.eval_cmd(Tk_CMDTBL[arg.shift], *arg)) @@ -1762,10 +1812,28 @@ module TkPack tk_call 'pack', 'forget' *args end - def propagate(master, bool=None) - bool(tk_call('pack', 'propagate', master.epath, bool)) + def info(slave) + ilist = list(tk_call('pack', 'info', slave.epath)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + return info end - module_function :configure, :forget, :propagate + + def propagate(master, bool=None) + if bool == None + bool(tk_call('pack', 'propagate', master.epath)) + else + tk_call('pack', 'propagate', master.epath, bool) + end + end + + def slaves(master) + list(tk_call('pack', 'slaves', master.epath)) + end + + module_function :configure, :forget, :info, :propagate, :slaves end module TkGrid @@ -1795,6 +1863,32 @@ module TkGrid tk_call "grid", 'rowconfigure', master, index, *hash_kv(args) end + def columnconfiginfo(master, index, slot=nil) + if slot + tk_call 'grid', 'columnconfigure', master, index, "-#{slot}" + else + ilist = list(tk_call('grid', 'columnconfigure', master, index)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + info + end + end + + def rowconfiginfo(master, index, slot=nil) + if slot + tk_call 'grid', 'rowconfigure', master, index, "-#{slot}" + else + ilist = list(tk_call('grid', 'rowconfigure', master, index)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + info + end + end + def add(widget, *args) configure(widget, *args) end @@ -1812,7 +1906,11 @@ module TkGrid end def propagate(master, bool=None) - bool(tk_call('grid', 'propagate', master.epath, bool)) + if bool == None + bool(tk_call('grid', 'propagate', master.epath)) + else + tk_call('grid', 'propagate', master.epath, bool) + end end def remove(*args) @@ -1823,13 +1921,63 @@ module TkGrid tk_call 'grid', 'size', master end - def slaves(args) - list(tk_call('grid', 'slaves', *hash_kv(args))) + def slaves(master, args) + list(tk_call('grid', 'slaves', master, *hash_kv(args))) end module_function :bbox, :forget, :propagate, :info module_function :remove, :size, :slaves, :location module_function :configure, :columnconfigure, :rowconfigure + module_function :columnconfiginfo, :rowconfiginfo +end + +module TkPlace + include Tk + extend Tk + + def configure(win, slot, value=None) + if slot.kind_of? Hash + tk_call 'place', 'configure', win.epath, *hash_kv(slot) + else + tk_call 'place', 'configure', win.epath, "-#{slot}", value + end + end + + def configinfo(win, slot = nil) + # for >= Tk8.4a2 ? + if slot + conf = tk_split_list(tk_call('place', 'configure', + win.epath, "-#{slot}") ) + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(tk_call('place', 'configure', + win.epath)).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + conf + } + end + end + + def forget(win) + tk_call 'place', 'forget', win + end + + def info(win) + ilist = list(tk_call('place', 'info', win.epath)) + info = {} + while key = ilist.shift + info[key[1..-1]] = ilist.shift + end + return info + end + + def slaves(master) + list(tk_call('place', 'slaves', master.epath)) + end + + module_function :configure, :configinfo, :forget, :info, :slaves end module TkOption @@ -1993,7 +2141,12 @@ class TkObject= Tk8.4a2 ? + if slot + conf = tk_split_list(tk_call('place', 'configure', epath, "-#{slot}") ) + conf[0] = conf[0][1..-1] + conf + else + tk_split_simplelist(tk_call('place', + 'configure', epath)).collect{|conflist| + conf = tk_split_simplelist(conflist) + conf[0] = conf[0][1..-1] + conf + } + end end def place_info() @@ -2128,19 +2432,6 @@ class TkWindowas.data.dfree) { + p->as.free.flag = 0; (*RANY(p)->as.data.dfree)(DATA_PTR(p)); } else if (BUILTIN_TYPE(p) == T_FILE) { + p->as.free.flag = 0; rb_io_fptr_finalize(RANY(p)->as.file.fptr); } p++; @@ -1310,14 +1312,14 @@ Init_GC() void* xmalloc(size) - size_t size; + long size; { return ruby_xmalloc(size); } void* xcalloc(n,size) - size_t n,size; + long n,size; { return ruby_xcalloc(n, size); } @@ -1325,7 +1327,7 @@ xcalloc(n,size) void* xrealloc(ptr,size) void *ptr; - size_t size; + long size; { return ruby_xrealloc(ptr, size); } diff --git a/intern.h b/intern.h index f36067b0ca..35ff93f80a 100644 --- a/intern.h +++ b/intern.h @@ -140,8 +140,9 @@ VALUE rb_class_new_instance _((int, VALUE*, VALUE)); VALUE rb_f_lambda _((void)); VALUE rb_protect _((VALUE (*)(), VALUE, int*)); void rb_set_end_proc _((void (*)(), VALUE)); -void rb_exec_end_proc _((void)); void rb_mark_end_proc _((void)); +void ruby_finalize _((void)); +void ruby_stop _((int)); void rb_gc_mark_threads _((void)); void rb_thread_start_timer _((void)); void rb_thread_stop_timer _((void)); @@ -167,6 +168,7 @@ VALUE rb_thread_current _((void)); VALUE rb_thread_main _((void)); VALUE rb_thread_local_aref _((VALUE, ID)); VALUE rb_thread_local_aset _((VALUE, ID, VALUE)); +void rb_thread_atfork _((void)); /* file.c */ int eaccess _((const char*, int)); VALUE rb_file_s_expand_path _((int, VALUE *)); diff --git a/io.c b/io.c index 38b11abba4..8c9ccc0ee4 100644 --- a/io.c +++ b/io.c @@ -2763,6 +2763,32 @@ rb_f_select(argc, argv, obj) return res; /* returns an empty array on interrupt */ } +static int +io_cntl(fd,cmd,narg,io_p) + int fd, cmd, io_p; + long narg; +{ + int retval; + +#ifdef HAVE_FCNTL + TRAP_BEG; +# if defined(__CYGWIN__) + retval = io_p?ioctl(fd, cmd, (void*)narg):fcntl(fd, cmd, narg); +# else + retval = io_p?ioctl(fd, cmd, narg):fcntl(fd, cmd, narg); +# endif + TRAP_END; +#else + if (!io_p) { + rb_notimplement(); + } + TRAP_BEG; + retval = ioctl(fd, cmd, narg); + TRAP_END; +#endif + return retval; +} + static VALUE rb_io_ctl(io, req, arg, io_p) VALUE io, req, arg; @@ -2772,7 +2798,6 @@ rb_io_ctl(io, req, arg, io_p) int cmd = NUM2ULONG(req); OpenFile *fptr; int len = 0; - int fd; long narg = 0; int retval; @@ -2812,27 +2837,16 @@ rb_io_ctl(io, req, arg, io_p) RSTRING(arg)->ptr[len] = 17; /* a little sanity check here */ narg = (long)RSTRING(arg)->ptr; } - fd = fileno(fptr->f); -#ifdef HAVE_FCNTL - TRAP_BEG; -# if defined(__CYGWIN__) - retval = io_p?ioctl(fd, cmd, (void*)narg):fcntl(fd, cmd, narg); -# else - retval = io_p?ioctl(fd, cmd, narg):fcntl(fd, cmd, narg); -# endif - TRAP_END; -#else - if (!io_p) { - rb_notimplement(); - } - TRAP_BEG; - retval = ioctl(fd, cmd, narg); - TRAP_END; -#endif + retval = io_cntl(fileno(fptr->f), cmd, narg, io_p); if (retval < 0) rb_sys_fail(fptr->path); if (TYPE(arg) == T_STRING && RSTRING(arg)->ptr[len] != 17) { rb_raise(rb_eArgError, "return value overflowed string"); } + + if (fptr->f2) { /* call on f2 too; ignore result */ + io_cntl(fileno(fptr->f2), cmd, narg, io_p); + } + return INT2NUM(retval); #else rb_notimplement(); diff --git a/numeric.c b/numeric.c index 0a172a3965..0dd86f0532 100644 --- a/numeric.c +++ b/numeric.c @@ -331,7 +331,7 @@ flodivmod(x, y, divp, modp) { double z; - modf(x/y, &); + modf(x/y, &z); mod = x - z * x; } #endif diff --git a/parse.y b/parse.y index 29cd1a4a27..e767ea2373 100644 --- a/parse.y +++ b/parse.y @@ -1956,7 +1956,6 @@ yycompile(f, line) n = yyparse(); ruby_debug_lines = 0; compile_for_eval = 0; - rb_gc(); ruby_in_compile = 0; cond_nest = 0; cond_stack = 0; diff --git a/process.c b/process.c index 31505c8578..657b316864 100644 --- a/process.c +++ b/process.c @@ -217,7 +217,10 @@ proc_waitpid(argc, argv) if ((pid = rb_waitpid(NUM2INT(vpid), flags, &status)) < 0) rb_sys_fail(0); - if (pid == 0) return Qnil; + if (pid == 0) { + rb_last_status = Qnil; + return Qnil; + } return INT2FIX(pid); } @@ -227,6 +230,7 @@ proc_waitpid2(argc, argv) VALUE *argv; { VALUE pid = proc_waitpid(argc, argv); + if (NIL_P(pid)) return Qnil; return rb_assoc_new(pid, rb_last_status); } @@ -526,6 +530,21 @@ rb_f_exec(argc, argv) return Qnil; /* dummy */ } +static VALUE +fork_rescue(data, errinfo) + VALUE data, errinfo; +{ + int status = 1; + + if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) { + VALUE st = rb_iv_get(errinfo, "status"); + + status = NUM2INT(st); + } + ruby_finalize(); + _exit(status); +} + static VALUE rb_f_fork(obj) VALUE obj; @@ -539,9 +558,17 @@ rb_f_fork(obj) #ifdef linux after_exec(); #endif + rb_thread_atfork(); if (rb_block_given_p()) { - rb_yield(Qnil); +#if 0 + rb_rescue2(rb_yield, Qnil, fork_rescue, 0, rb_eException, 0); _exit(0); +#else + int status; + + rb_protect(rb_yield, Qnil, &status); + ruby_stop(status); +#endif } return Qnil; diff --git a/range.c b/range.c index 96f9fd6bb0..ed835c2d4c 100644 --- a/range.c +++ b/range.c @@ -13,10 +13,10 @@ #include "ruby.h" VALUE rb_cRange; -static ID id_cmp, id_beg, id_end; +static ID id_cmp, id_beg, id_end, id_excl; -#define EXCL(r) FL_TEST((r), FL_USER1) -#define SET_EXCL(r) FL_SET((r), FL_USER1) +#define EXCL(r) RTEST(rb_ivar_get((r), id_excl)) +#define SET_EXCL(r,v) rb_ivar_set((r), id_excl, (v)?Qtrue:Qfalse) static VALUE range_check(args) @@ -46,10 +46,7 @@ range_init(obj, beg, end, exclude_end) rb_eStandardError, rb_eNameError, 0); } - if (exclude_end) { - SET_EXCL(obj); - } - + SET_EXCL(obj, exclude_end); rb_ivar_set(obj, id_beg, beg); rb_ivar_set(obj, id_end, end); } @@ -89,6 +86,22 @@ range_exclude_end_p(range) return EXCL(range)?Qtrue:Qfalse; } +static VALUE +range_eq(range, obj) + VALUE range, obj; +{ + if (!rb_obj_is_kind_of(obj, rb_cRange)) return Qfalse; + + if (!rb_equal(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg))) + return Qfalse; + if (!rb_equal(rb_ivar_get(range, id_end), rb_ivar_get(obj, id_end))) + return Qfalse; + + if (EXCL(range) != EXCL(obj)) return Qfalse; + + return Qtrue; +} + static VALUE range_eqq(range, obj) VALUE range, obj; @@ -338,6 +351,7 @@ Init_Range() rb_cRange = rb_define_class("Range", rb_cObject); rb_include_module(rb_cRange, rb_mEnumerable); rb_define_method(rb_cRange, "initialize", range_initialize, -1); + rb_define_method(rb_cRange, "==", range_eq, 1); rb_define_method(rb_cRange, "===", range_eqq, 1); rb_define_method(rb_cRange, "each", range_each, 0); rb_define_method(rb_cRange, "first", range_first, 0); @@ -355,4 +369,5 @@ Init_Range() id_cmp = rb_intern("<=>"); id_beg = rb_intern("begin"); id_end = rb_intern("end"); + id_excl = rb_intern("excl"); } diff --git a/ruby.h b/ruby.h index 8dd280148d..ca97ee2c42 100644 --- a/ruby.h +++ b/ruby.h @@ -380,9 +380,9 @@ struct RBignum { #define xrealloc ruby_xrealloc #define xfree ruby_xfree -void *xmalloc _((size_t)); -void *xcalloc _((size_t,size_t)); -void *xrealloc _((void*,size_t)); +void *xmalloc _((long)); +void *xcalloc _((long,long)); +void *xrealloc _((void*,long)); void xfree _((void*)); #define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n)) diff --git a/sample/fib.scm b/sample/fib.scm index 5c2b86e656..b246ca50ac 100644 --- a/sample/fib.scm +++ b/sample/fib.scm @@ -5,4 +5,4 @@ (display (fib 20)) (newline) - +(quit) diff --git a/signal.c b/signal.c index 77233c1852..2bb8bada28 100644 --- a/signal.c +++ b/signal.c @@ -391,7 +391,10 @@ rb_trap_exit() { #ifndef MACOS_UNUSE_SIGNAL if (trap_list[0]) { - rb_eval_cmd(trap_list[0], rb_ary_new3(1, INT2FIX(0))); + VALUE trap_exit = trap_list[0]; + + trap_list[0] = 0; + rb_eval_cmd(trap_exit, rb_ary_new3(1, INT2FIX(0))); } #endif } diff --git a/variable.c b/variable.c index dbc1967d02..d2669aaf6f 100644 --- a/variable.c +++ b/variable.c @@ -1480,6 +1480,10 @@ rb_mod_class_variables(obj) if (!OBJ_TAINTED(obj) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't get metainfo"); + if (FL_TEST(obj, FL_SINGLETON)) { + obj = rb_cvar_singleton(rb_iv_get(obj, "__attached__")); + } + for (;;) { if (RCLASS(obj)->iv_tbl) { st_foreach(RCLASS(obj)->iv_tbl, cv_i, ary); diff --git a/version.h b/version.h index cf50770ad1..807a73e239 100644 --- a/version.h +++ b/version.h @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.6.2" -#define RUBY_RELEASE_DATE "2000-11-21" +#define RUBY_RELEASE_DATE "2000-11-27" #define RUBY_VERSION_CODE 162 -#define RUBY_RELEASE_CODE 20001121 +#define RUBY_RELEASE_CODE 20001127