Bugs: Browse | Submit New | Admin

[#6400] Time Does not Respect Subclasses

Date:
2006-10-30 18:20
Priority:
3
Submitted By:
David Wheeler (theory)
Assigned To:
Nobody (None)
Category:
Language / Runtime / Core Libraries
State:
Open
Platform:
 
Summary:
Time Does not Respect Subclasses

Detailed description
Some of the core Time class constructors do not return objects in the proper class for subclasses:

  require 'time'
  class MyTime < Time
  end
  puts MyTime.parse("16:30").class

This example outputs "Time"; I would argue that it should output "MyTime". IOW, constructors should
return objects of the class on which the constructor was called.

The methods that have this bug include:

  Time.parse()
  Time.httpdate()
  Time.rfc2822()
  Time.rfc822()
  Time#getlocal()
  Time#getutc()
  Time#getgm()

Thanks!

Add A Comment: Notepad

Please login


Followup

Message
Date: 2007-10-05 15:03
Sender: Ron Leisti

Here are two patches, one for the 1.8 branch and one for 1.9,
which fix the Time#+ and Time#- methods:

Ruby 1.8
========

Index: time.c
=================================================================
==
--- time.c	(revision 13639)
+++ time.c	(working copy)
@@ -1283,17 +1283,20 @@
 }
 
 static VALUE
-time_add(tobj, offset, sign)
-    struct time_object *tobj;
+time_add(time, offset, sign)
+    VALUE time;
     VALUE offset;
     int sign;
 {
     double v = NUM2DBL(offset);
     double f, d;
+    struct time_object *tobj;
     unsigned_time_t sec_off;
     time_t usec_off, sec, usec;
     VALUE result;
 
+    GetTimeval(time, tobj);
+
     if (v < 0) {
         v = -v;
         sign = -sign;
@@ -1317,11 +1320,12 @@
         if (sec < tobj->tv.tv_sec)
             rb_raise(rb_eRangeError, "time + %f out of
Time range", v);
     }
-    result = rb_time_new(sec, usec);
-    if (tobj->gmt) {
-	GetTimeval(result, tobj);
-	tobj->gmt = 1;
-    }
+    result = time_dup(time);
+    GetTimeval(result, tobj);
+    time_overflow_p(&sec, &usec);
+    tobj->tv.tv_sec = sec;
+    tobj->tv.tv_usec = usec;
+    time_get_tm(result, tobj->gmt);
     return result;
 }
 
@@ -1346,7 +1350,7 @@
     if (TYPE(time2) == T_DATA && RDATA(time2)->dfree
== time_free) {
 	rb_raise(rb_eTypeError, "time + time?");
     }
-    return time_add(tobj, time2, 1);
+    return time_add(time1, time2, 1);
 }
 
 /*
@@ -1382,7 +1386,7 @@
 
 	return rb_float_new(f);
     }
-    return time_add(tobj, time2, -1);
+    return time_add(time1, time2, -1);
 }
 
 /*

Ruby 1.9
========

Index: time.c
=================================================================
==
--- time.c	(revision 13639)
+++ time.c	(working copy)
@@ -1232,14 +1232,17 @@
 }
 
 static VALUE
-time_add(struct time_object *tobj, VALUE offset, int sign)
+time_add(VALUE time, VALUE offset, int sign)
 {
+    struct time_object *tobj;
     double v = NUM2DBL(offset);
     double f, d;
     unsigned_time_t sec_off;
     time_t usec_off, sec, usec;
     VALUE result;
 
+    GetTimeval(time, tobj);
+
     if (v < 0) {
 	v = -v;
 	sign = -sign;
@@ -1263,11 +1266,12 @@
 	if (sec < tobj->tv.tv_sec)
 	    rb_raise(rb_eRangeError, "time + %f out of Time
range", v);
     }
-    result = rb_time_new(sec, usec);
-    if (tobj->gmt) {
-	GetTimeval(result, tobj);
-	tobj->gmt = 1;
-    }
+    result = time_dup(time);
+    GetTimeval(result, tobj);
+    time_overflow_p(&sec, &usec);
+    tobj->tv.tv_sec = sec;
+    tobj->tv.tv_usec = usec;
+    time_get_tm(result, tobj->gmt);
     return result;
 }
 
@@ -1291,7 +1295,7 @@
     if (TYPE(time2) == T_DATA && RDATA(time2)->dfree
== time_free) {
 	rb_raise(rb_eTypeError, "time + time?");
     }
-    return time_add(tobj, time2, 1);
+    return time_add(time1, time2, 1);
 }
 
 /*
@@ -1326,7 +1330,7 @@
 
 	return rb_float_new(f);
     }
-    return time_add(tobj, time2, -1);
+    return time_add(time1, time2, -1);
 }
 
 /*
Date: 2006-11-02 12:51
Sender: David Wheeler

The patch also does not fix

  Time#+
  Time#-

Thanks!
Date: 2006-11-02 12:50
Sender: David Wheeler

The patch does fix these class methods:

  Time.parse()
  Time.httpdate()
  Time.rfc2822()
  Time.rfc822()

But not these instance methods:

  Time#getlocal()
  Time#getutc()
  Time#getgm()

Looks like those are implemented in C.
Date: 2006-11-02 07:04
Sender: Ryan Davis

Please test the attached patch for time.rb class methods.
Date: 2006-10-31 06:28
Sender: David Wheeler

A couple more to add to the list:

  Time.+
  Time.-

Thanks!

Attached Files:

Name Description Download
time.rb.patch Download

Changes:

Field Old Value Date By
assigned_tozenspider2009-02-17 23:12zenspider
category_idMisc / Other Standard Library2007-05-29 21:55zenspider
category_idLanguage / Runtime / Core Libraries2007-05-29 15:54zenspider
assigned_tonone2006-11-02 07:07zenspider
File Added912: time.rb.patch2006-11-02 07:04zenspider