From d497898c231f124ba187e2650be8af20b47b1a97 Mon Sep 17 00:00:00 2001 From: matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Fri, 8 Mar 2002 07:03:09 +0000 Subject: [PATCH] * eval.c (cvar_cbase): utility function to find innermost non singleton cbase. * eval.c (is_defined): adopt new cvar behavior. * eval.c (rb_eval): ditto. * eval.c (assign): ditto. * class.c (rb_mod_clone): should not call rb_obj_clone(), since Module does not provide "allocate". * class.c (rb_singleton_class): should crate new singleton class if obj is a class or module and attached object is different, which means metaclass of singleton class is sought. * time.c (time_s_alloc): now follows allocation framework. * eval.c (rb_eval): should initialize outer class variables from methods in singleton class definitions. * eval.c (assign): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2169 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 29 +++++++++++++++ array.c | 2 +- class.c | 20 ++++++++-- eval.c | 82 ++++++++++++++++------------------------- ext/tcltklib/tcltklib.c | 25 +++++++++++++ ext/tk/lib/tk.rb | 47 +++++++++++++---------- ext/tk/lib/tkfont.rb | 18 ++++++++- ext/tk/lib/tktext.rb | 2 +- hash.c | 4 +- object.c | 12 +++--- parse.y | 1 + sample/test.rb | 11 ++++++ signal.c | 2 +- time.c | 13 +++++-- 14 files changed, 180 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4c97401f8d..22ba21d110 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,17 @@ Fri Mar 8 12:19:15 2002 Tanaka Akira <akr@m17n.org> * lib/resolv.rb: use its own thread group for background threads. +Fri Mar 8 02:21:32 2002 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (cvar_cbase): utility function to find innermost non + singleton cbase. + + * eval.c (is_defined): adopt new cvar behavior. + + * eval.c (rb_eval): ditto. + + * eval.c (assign): ditto. + Thu Mar 7 20:08:25 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp> * gc.c (rb_source_filename): added. holds unique strings for file @@ -31,6 +42,17 @@ Wed Mar 6 17:58:08 2002 WATANABE Hirofumi <eban@ruby-lang.org> * dln.c (dln_load): use LoadLibrary instead of LoadLibraryEx. +Wed Mar 6 16:50:37 2002 Yukihiro Matsumoto <matz@ruby-lang.org> + + * class.c (rb_mod_clone): should not call rb_obj_clone(), since + Module does not provide "allocate". + + * class.c (rb_singleton_class): should crate new singleton class + if obj is a class or module and attached object is different, + which means metaclass of singleton class is sought. + + * time.c (time_s_alloc): now follows allocation framework. + Tue Mar 5 05:56:29 2002 Akinori MUSHA <knu@iDaemons.org> * lib/getopts.rb: Rewrite to fix some bugs and complete features. @@ -48,6 +70,13 @@ Mon Mar 4 13:19:18 2002 Akinori MUSHA <knu@iDaemons.org> --with-xx-{include,lib} is ignored when --with-xx-dir is specified. +Mon Mar 4 00:09:55 2002 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_eval): should initialize outer class variables from + methods in singleton class definitions. + + * eval.c (assign): ditto. + Fri Mar 1 11:29:10 2002 WATANABE Hirofumi <eban@ruby-lang.org> * ext/socket/{addinfo.h,getaddrinfo.c} (gai_strerror): add const diff --git a/array.c b/array.c index f772325d06..18f08ce532 100644 --- a/array.c +++ b/array.c @@ -402,7 +402,7 @@ rb_ary_unshift(ary, item) VALUE ary, item; { rb_ary_modify(ary); - if (RARRAY(ary)->len >= RARRAY(ary)->aux.capa) { + if (RARRAY(ary)->len == RARRAY(ary)->aux.capa) { long capa_inc = RARRAY(ary)->aux.capa / 2; if (capa_inc < ARY_DEFAULT_SIZE) { capa_inc = ARY_DEFAULT_SIZE; diff --git a/class.c b/class.c index 12d03f15e4..e0445cd934 100644 --- a/class.c +++ b/class.c @@ -62,7 +62,8 @@ VALUE rb_mod_clone(module) VALUE module; { - VALUE clone = rb_obj_clone(module); + NEWOBJ(clone, struct RClass); + CLONESETUP(clone, module); RCLASS(clone)->super = RCLASS(module)->super; if (RCLASS(module)->iv_tbl) { @@ -79,7 +80,7 @@ rb_mod_clone(module) st_foreach(RCLASS(module)->m_tbl, clone_method, RCLASS(clone)->m_tbl); } - return clone; + return (VALUE)clone; } VALUE @@ -652,6 +653,8 @@ rb_undef_method(klass, name) rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF); } +#if 0 + #define SPECIAL_SINGLETON(x,c) if (obj == (x)) {\ if (!FL_TEST(c, FL_SINGLETON)) {\ c = rb_singleton_class_new(c);\ @@ -660,6 +663,14 @@ rb_undef_method(klass, name) return c;\ } +#else + +#define SPECIAL_SINGLETON(x,c) if (obj == (x)) {\ + return c;\ +} + +#endif + VALUE rb_singleton_class(obj) VALUE obj; @@ -677,11 +688,14 @@ rb_singleton_class(obj) } DEFER_INTS; - if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) { + if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && + (BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE) && + rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); + RBASIC(klass)->klass = CLASS_OF(RCLASS(klass)->super); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); diff --git a/eval.c b/eval.c index 759e041802..ec78879c65 100644 --- a/eval.c +++ b/eval.c @@ -1493,10 +1493,10 @@ ev_const_get(cref, id, self) VALUE result; while (cbase && cbase->nd_next) { - struct RClass *klass = RCLASS(cbase->nd_clss); + VALUE klass = cbase->nd_clss; if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id); - if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) { + if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) { return result; } cbase = cbase->nd_next; @@ -1504,6 +1504,20 @@ ev_const_get(cref, id, self) return rb_const_get(cref->nd_clss, id); } +static VALUE +cvar_cbase() +{ + NODE *cref = RNODE(ruby_frame->cbase); + + while (cref && cref->nd_next && FL_TEST(cref->nd_clss, FL_SINGLETON)) { + cref = cref->nd_next; + if (!cref->nd_next) { + rb_warn("class variable access from toplevel singleton method"); + } + } + return cref->nd_clss; +} + static VALUE rb_mod_nesting() { @@ -1901,19 +1915,7 @@ is_defined(self, node, buf) break; case NODE_CVAR: - if (NIL_P(ruby_cbase)) { - if (rb_cvar_defined(CLASS_OF(self), node->nd_vid)) { - return "class variable"; - } - break; - } - if (!FL_TEST(ruby_cbase, FL_SINGLETON)) { - if (rb_cvar_defined(ruby_cbase, node->nd_vid)) { - return "class variable"; - } - break; - } - if (rb_cvar_defined(rb_iv_get(ruby_cbase, "__attached__"), node->nd_vid)) { + if (rb_cvar_defined(cvar_cbase(), node->nd_vid)) { return "class variable"; } break; @@ -2871,15 +2873,12 @@ rb_eval(self, n) rb_raise(rb_eTypeError, "no class/module to define class variable"); } result = rb_eval(self, node->nd_value); - if (ruby_verbose && FL_TEST(ruby_cbase, FL_SINGLETON)) { - rb_warn("declaring singleton class variable"); - } - rb_cvar_set(ruby_cbase, node->nd_vid, result, Qtrue); + rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qtrue); break; case NODE_CVASGN: result = rb_eval(self, node->nd_value); - rb_cvar_set(ruby_cbase, node->nd_vid, result, Qfalse); + rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qfalse); break; case NODE_LVAR: @@ -2906,15 +2905,7 @@ rb_eval(self, n) break; case NODE_CVAR: - if (NIL_P(ruby_cbase)) { - result = rb_cvar_get(CLASS_OF(self), node->nd_vid); - break; - } - if (!FL_TEST(ruby_cbase, FL_SINGLETON)) { - result = rb_cvar_get(ruby_cbase, node->nd_vid); - break; - } - result = rb_cvar_get(rb_iv_get(ruby_cbase, "__attached__"), node->nd_vid); + result = rb_cvar_get(cvar_cbase(), node->nd_vid); break; case NODE_BLOCK_ARG: @@ -3164,7 +3155,7 @@ rb_eval(self, n) NODE *body = 0, *defn; if (rb_safe_level() >= 4 && !OBJ_TAINTED(recv)) { - rb_raise(rb_eSecurityError, "Insecure; can't define singleton method"); + rb_raise(rb_eSecurityError, "Insecure: can't define singleton method"); } if (FIXNUM_P(recv) || SYMBOL_P(recv)) { rb_raise(rb_eTypeError, @@ -3308,24 +3299,13 @@ rb_eval(self, n) VALUE klass; result = rb_eval(self, node->nd_recv); - if (result == Qtrue) { - klass = rb_cTrueClass; - } - else if (result == Qfalse) { - klass = rb_cTrueClass; - } - else if (result == Qnil) { - klass = rb_cNilClass; - } - else { - if (rb_special_const_p(result)) { - rb_raise(rb_eTypeError, "no virtual class for %s", - rb_class2name(CLASS_OF(result))); - } - if (rb_safe_level() >= 4 && !OBJ_TAINTED(result)) - rb_raise(rb_eSecurityError, "Insecure: can't extend object"); - klass = rb_singleton_class(result); + if (FIXNUM_P(result) || SYMBOL_P(result)) { + rb_raise(rb_eTypeError, "no virtual class for %s", + rb_class2name(CLASS_OF(result))); } + if (rb_safe_level() >= 4 && !OBJ_TAINTED(result)) + rb_raise(rb_eSecurityError, "Insecure: can't extend object"); + klass = rb_singleton_class(result); if (ruby_wrapper) { rb_extend_object(klass, ruby_wrapper); @@ -3936,11 +3916,11 @@ assign(self, lhs, val, pcall) if (ruby_verbose && FL_TEST(ruby_cbase, FL_SINGLETON)) { rb_warn("declaring singleton class variable"); } - rb_cvar_set(ruby_cbase, lhs->nd_vid, val, Qtrue); + rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qtrue); break; case NODE_CVASGN: - rb_cvar_set(ruby_cbase, lhs->nd_vid, val, Qfalse); + rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qfalse); break; case NODE_MASGN: @@ -5848,8 +5828,8 @@ rb_obj_extend(argc, argv, obj) rb_raise(rb_eArgError, "wrong number of arguments(0 for 1)"); } for (i=0; i<argc; i++) Check_Type(argv[i], T_MODULE); - for (i=0; i<argc; i++) { - rb_funcall(argv[i], rb_intern("extend_object"), 1, obj); + while (argc--) { + rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj); } return obj; } diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index e9c2b56fc1..7acbacdd94 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -120,6 +120,30 @@ ip_eval_rescue(failed, einfo) return Qnil; } +/* restart Tk */ +static VALUE +lib_restart(self) + VALUE self; +{ + struct tcltkip *ptr; /* tcltkip data struct */ + + /* get the data struct */ + Data_Get_Struct(self, struct tcltkip, ptr); + + /* destroy the root wdiget */ + ptr->return_value = Tcl_Eval(ptr->ip, "destroy ."); + /* ignore ERROR */ + DUMP2("(TCL_Eval result) %d", ptr->return_value); + + /* execute Tk_Init */ + DUMP1("Tk_Init"); + if (Tk_Init(ptr->ip) == TCL_ERROR) { + rb_raise(rb_eRuntimeError, "%s", ptr->ip->result); + } + + return Qnil; +} + static int #if TCL_MAJOR_VERSION >= 8 ip_ruby(clientData, interp, argc, argv) @@ -521,6 +545,7 @@ Init_tcltklib() rb_define_method(ip, "_invoke", ip_invoke, -1); rb_define_method(ip, "_return_value", ip_retval, 0); rb_define_method(ip, "mainloop", lib_mainloop, 0); + rb_define_method(ip, "restart", lib_restart, 0); main_thread = rb_thread_current(); #ifdef __MACOS__ diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index a16694bf76..a935a55e16 100644 --- a/ext/tk/lib/tk.rb +++ b/ext/tk/lib/tk.rb @@ -450,11 +450,11 @@ module TkComm end def pack(*args) - TkPack.configure *args + TkPack.configure(*args) end def grid(*args) - TkGrid.configure *args + TkGrid.configure(*args) end def update(idle=nil) @@ -495,18 +495,18 @@ module TkCore myid = _curr_cmd_id cmdid = install_cmd(cmd) tk_call("after",ms,cmdid) - return - if false #defined? Thread - Thread.start do - ms = Float(ms)/1000 - ms = 10 if ms == 0 - sleep ms/1000 - cmd.call - end - else - cmdid = install_cmd(cmd) - tk_call("after",ms,cmdid) - end +# return +# if false #defined? Thread +# Thread.start do +# ms = Float(ms)/1000 +# ms = 10 if ms == 0 +# sleep ms/1000 +# cmd.call +# end +# else +# cmdid = install_cmd(cmd) +# tk_call("after",ms,cmdid) +# end end def after_idle(cmd=Proc.new) @@ -620,6 +620,12 @@ module TkCore TclTkLib.mainloop end + def restart + TkCore::INTERP.restart + TkComm::Tk_WINDOWS.clear + nil + end + def event_generate(window, context, keys=nil) window = window.path if window.kind_of? TkObject if keys @@ -651,10 +657,11 @@ module TkCore end def tk_call(*args) - print args.join(" "), "\n" if $DEBUG + puts args.inspect if $DEBUG args.collect! {|x|ruby2tcl(x)} args.compact! args.flatten! + print "=> ", args.join(" ").inspect, "\n" if $DEBUG begin res = INTERP._invoke(*args) rescue NameError @@ -670,7 +677,7 @@ module TkCore if INTERP._return_value() != 0 fail RuntimeError, res, error_at end - print "==> ", res, "\n" if $DEBUG + print "==> ", res.inspect, "\n" if $DEBUG return res end end @@ -830,8 +837,8 @@ module Tk if bar @xscrollbar = bar @xscrollbar.orient 'horizontal' - self.xscrollcommand {|arg| @xscrollbar.set *arg} - @xscrollbar.command {|arg| self.xview *arg} + self.xscrollcommand {|arg| @xscrollbar.set(*arg)} + @xscrollbar.command {|arg| self.xview(*arg)} end @xscrollbar end @@ -839,8 +846,8 @@ module Tk if bar @yscrollbar = bar @yscrollbar.orient 'vertical' - self.yscrollcommand {|arg| @yscrollbar.set *arg} - @yscrollbar.command {|arg| self.yview *arg} + self.yscrollcommand {|arg| @yscrollbar.set(*arg)} + @yscrollbar.command {|arg| self.yview(*arg)} end @yscrollbar end diff --git a/ext/tk/lib/tkfont.rb b/ext/tk/lib/tkfont.rb index 42cce80fa3..c84d0960ed 100644 --- a/ext/tk/lib/tkfont.rb +++ b/ext/tk/lib/tkfont.rb @@ -758,9 +758,25 @@ class TkFont ################################### public ################################### + def method_missing(id, *args) + name = id.id2name + case args.length + when 1 + configure name, args[0] + when 0 + begin + configinfo name + rescue + fail NameError, "undefined local variable or method `#{name}' for #{self.to_s}", error_at + end + else + fail NameError, "undefined method `#{name}' for #{self.to_s}", error_at + end + end + def call_font_configure(path, *args) args += hash_kv(args.pop.update(@fontslot)) - tk_call *args + tk_call(*args) Tk_FontUseTBL[path] = self self end diff --git a/ext/tk/lib/tktext.rb b/ext/tk/lib/tktext.rb index 493506f7ed..75b28d8477 100644 --- a/ext/tk/lib/tktext.rb +++ b/ext/tk/lib/tktext.rb @@ -38,7 +38,7 @@ class TkText<TkTextWin def self.new(*args, &block) obj = super(*args){} obj.init_instance_variable - obj.instance_eval &block if defined? yield + obj.instance_eval(&block) if defined? yield obj end diff --git a/hash.c b/hash.c index 468830a075..170913dc18 100644 --- a/hash.c +++ b/hash.c @@ -97,10 +97,10 @@ rb_any_hash(a) DEFER_INTS; hval = rb_funcall(a, id_hash, 0); if (FIXNUM_P(hval)) { - hval %= 536870917; + hval %= 536870923; } else { - hval = rb_funcall(hval, '%', 1, INT2FIX(536870917)); + hval = rb_funcall(hval, '%', 1, INT2FIX(536870923)); } ENABLE_INTS; return (int)FIX2LONG(hval); diff --git a/object.c b/object.c index bf22075369..a954d8ad88 100644 --- a/object.c +++ b/object.c @@ -97,7 +97,7 @@ rb_obj_clone(obj) if (rb_special_const_p(obj)) { rb_raise(rb_eTypeError, "can't clone %s", rb_class2name(CLASS_OF(obj))); } - clone = rb_obj_alloc(RBASIC(obj)->klass); + clone = rb_obj_alloc(rb_class_real(RBASIC(obj)->klass)); CLONESETUP(clone,obj); if (TYPE(clone) == T_OBJECT && ROBJECT(obj)->iv_tbl) { ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl); @@ -658,7 +658,12 @@ VALUE rb_obj_alloc(klass) VALUE klass; { - VALUE obj = rb_funcall(klass, alloc, 0, 0); + VALUE obj; + + if (FL_TEST(klass, FL_SINGLETON)) { + rb_raise(rb_eTypeError, "can't create instance of virtual class"); + } + obj = rb_funcall(klass, alloc, 0, 0); if (rb_obj_class(obj) != rb_class_real(klass)) { rb_raise(rb_eTypeError, "wrong instance allocation"); @@ -684,9 +689,6 @@ rb_class_new_instance(argc, argv, klass) { VALUE obj; - if (FL_TEST(klass, FL_SINGLETON)) { - rb_raise(rb_eTypeError, "can't create instance of virtual class"); - } obj = rb_obj_alloc(klass); rb_obj_call_init(obj, argc, argv); diff --git a/parse.y b/parse.y index ee36daf7ae..b94f1c0c61 100644 --- a/parse.y +++ b/parse.y @@ -2994,6 +2994,7 @@ yylex() case EXPR_BEG: case EXPR_FNAME: case EXPR_DOT: + case EXPR_CLASS: goto retry; default: break; diff --git a/sample/test.rb b/sample/test.rb index 82b159a7b7..1f6b140951 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -1351,6 +1351,17 @@ atlas = Titans.new test_ok(atlas.ruler0 == "Cronus") test_ok(atlas.ruler3 == "Zeus") +class <<a="a" + def foo=(n) + @@cv=n + end + def foo + @@cv + end +end +a.foo=5 +test_ok(a.foo == 5) + test_check "trace" $x = 1234 $y = 0 diff --git a/signal.c b/signal.c index 7d3b424725..2ff32e52dc 100644 --- a/signal.c +++ b/signal.c @@ -531,7 +531,7 @@ trap(arg) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) - rb_raise(rb_eArgError, "invalid signal SIG%s", s); + rb_raise(rb_eArgError, "unsupported signal SIG%s", s); } if (sig < 0 || sig > NSIG) { diff --git a/time.c b/time.c index 32b9f1118c..1f0cf2736e 100644 --- a/time.c +++ b/time.c @@ -45,7 +45,7 @@ struct time_object { } static VALUE -time_s_now(klass) +time_s_alloc(klass) VALUE klass; { VALUE obj; @@ -53,7 +53,6 @@ time_s_now(klass) obj = Data_Make_Struct(klass, struct time_object, 0, free, tobj); tobj->tm_got=0; - if (gettimeofday(&tobj->tv, 0) < 0) { rb_sys_fail("gettimeofday"); } @@ -61,6 +60,14 @@ time_s_now(klass) return obj; } +static VALUE +time_s_now(klass) + VALUE klass; +{ + return rb_obj_alloc(klass); +} + + #define NDIV(x,y) (-(-((x)+1)/(y))-1) #define NMOD(x,y) ((y)-(-((x)+1)%(y))-1) @@ -1413,7 +1420,7 @@ Init_Time() rb_include_module(rb_cTime, rb_mComparable); rb_define_singleton_method(rb_cTime, "now", time_s_now, 0); - rb_define_singleton_method(rb_cTime, "allocate", time_s_now, 0); + rb_define_singleton_method(rb_cTime, "allocate", time_s_alloc, 0); rb_define_singleton_method(rb_cTime, "at", time_s_at, -1); rb_define_singleton_method(rb_cTime, "utc", time_s_mkutc, -1); rb_define_singleton_method(rb_cTime, "gm", time_s_mkutc, -1);