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);