Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Enable allocate class method for Date and DateTime

Also, change dup and clone to call super instead of using
DUPSETUP and CLONESETUP.  This makes dup and clone work
correctly on rubinius.  It also makes dup and clone work
correctly for Date on jruby, but not for DateTime due to
a bug in JRuby.

allocate is defined to use the julian day 0 for simplicity.
  • Loading branch information...
commit ba9a86ff668615d0b619b69ff861f4e740c6865a 1 parent a0afad3
@jeremyevans authored
View
5 README.rdoc
@@ -182,9 +182,8 @@ you use the standard library.
* DateTime offsets are stored in minutes, so it will round offsets
with fractional minutes to the nearest minute.
* All public class and instance methods for both Date and DateTime
- are implemented, except that the allocate class method is not
- available and on 1.9, _dump and _load are used instead of
- marshal_dump and marshal_load.
+ are implemented, except that on 1.9, _dump and _load are used
+ instead of marshal_dump and marshal_load.
* Only the public API is compatible, the private methods in the
standard library are not implemented.
* The marshalling format differs from the one used by the standard
View
34 ext/date_ext/date_ext.c
@@ -1517,6 +1517,18 @@ static VALUE rhrd_s__strptime(int argc, VALUE *argv, VALUE klass) {
}
/* call-seq:
+ * allocate() -> Date <br />
+ *
+ * Returns a +Date+ object for julian day 0.
+ */
+static VALUE rhrd_s_allocate(VALUE klass) {
+ rhrd_t *d;
+ VALUE rd = Data_Make_Struct(klass, rhrd_t, NULL, -1, d);
+ d->flags = RHR_HAVE_JD;
+ return rd;
+}
+
+/* call-seq:
* civil() -> Date <br />
* civil(year, month=1, day=1, sg=nil) -> Date
*
@@ -2095,10 +2107,12 @@ static VALUE rhrd_asctime(VALUE self) {
*/
static VALUE rhrd_clone(VALUE self) {
rhrd_t *d, *nd;
- VALUE rd = Data_Make_Struct(rb_obj_class(self), rhrd_t, NULL, -1, nd);
- Data_Get_Struct(self, rhrd_t, d);
- memcpy(nd, d, sizeof(rhrd_t));
- CLONESETUP(rd, self);
+ VALUE rd = rb_call_super(0, NULL);
+ if (!rb_obj_is_kind_of(self, rhrdt_class)) {
+ Data_Get_Struct(self, rhrd_t, d);
+ Data_Get_Struct(rd, rhrd_t, nd);
+ memcpy(nd, d, sizeof(rhrd_t));
+ }
return rd;
}
@@ -2222,10 +2236,12 @@ static VALUE rhrd_downto(VALUE self, VALUE other) {
*/
static VALUE rhrd_dup(VALUE self) {
rhrd_t *d, *nd;
- VALUE rd = Data_Make_Struct(rb_obj_class(self), rhrd_t, NULL, -1, nd);
- Data_Get_Struct(self, rhrd_t, d);
- memcpy(nd, d, sizeof(rhrd_t));
- DUPSETUP(rd, self);
+ VALUE rd = rb_call_super(0, NULL);
+ if (!rb_obj_is_kind_of(self, rhrdt_class)) {
+ Data_Get_Struct(self, rhrd_t, d);
+ Data_Get_Struct(rd, rhrd_t, nd);
+ memcpy(nd, d, sizeof(rhrd_t));
+ }
return rd;
}
@@ -4065,7 +4081,7 @@ void Init_date_ext(void) {
/* Define classes*/
rhrd_class = rb_define_class("Date", rb_cObject);
- rb_undef_alloc_func(rhrd_class);
+ rb_define_alloc_func(rhrd_class, rhrd_s_allocate);
rhrd_s_class = rb_singleton_class(rhrd_class);
/* Define methods for all ruby versions */
View
21 ext/date_ext/datetime.c
@@ -580,6 +580,18 @@ static VALUE rhrdt_s__strptime(int argc, VALUE *argv, VALUE klass) {
}
/* call-seq:
+ * allocate() -> DateTime <br />
+ *
+ * Returns a +DateTime+ object for julian day 0.
+ */
+static VALUE rhrdt_s_allocate(VALUE klass) {
+ rhrdt_t *d;
+ VALUE rd = Data_Make_Struct(klass, rhrdt_t, NULL, -1, d);
+ d->flags = RHR_HAVE_JD | RHR_HAVE_NANOS;
+ return rd;
+}
+
+/* call-seq:
* civil() -> DateTime <br />
* civil(year, month=1, day=1, hour=0, minute=0, second=0, offset=0, sg=nil) -> DateTime
*
@@ -1007,10 +1019,10 @@ static VALUE rhrdt_asctime(VALUE self) {
*/
static VALUE rhrdt_clone(VALUE self) {
rhrdt_t *d, *nd;
- VALUE rd = Data_Make_Struct(rb_obj_class(self), rhrdt_t, NULL, -1, nd);
+ VALUE rd = rb_call_super(0, NULL);
Data_Get_Struct(self, rhrdt_t, d);
+ Data_Get_Struct(rd, rhrdt_t, nd);
memcpy(nd, d, sizeof(rhrdt_t));
- CLONESETUP(rd, self);
return rd;
}
@@ -1124,10 +1136,10 @@ static VALUE rhrdt_day_fraction(VALUE self) {
*/
static VALUE rhrdt_dup(VALUE self) {
rhrdt_t *d, *nd;
- VALUE rd = Data_Make_Struct(rb_obj_class(self), rhrdt_t, NULL, -1, nd);
+ VALUE rd = rb_call_super(0, NULL);
Data_Get_Struct(self, rhrdt_t, d);
+ Data_Get_Struct(rd, rhrdt_t, nd);
memcpy(nd, d, sizeof(rhrdt_t));
- DUPSETUP(rd, self);
return rd;
}
@@ -2769,6 +2781,7 @@ void Init_datetime(void) {
/* Define class */
rhrdt_class = rb_define_class("DateTime", rhrd_class);
+ rb_define_alloc_func(rhrdt_class, rhrdt_s_allocate);
rhrdt_s_class = rb_singleton_class(rhrdt_class);
/* Define methods for all ruby versions*/
View
4 spec/date/allocate_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path('../../spec_helper', __FILE__)
describe "Date.allocate" do
- it "should not be defined" do
- proc{Date.allocate}.should raise_error
+ it "should be the same as jd" do
+ Date.allocate.should == Date.jd
end
end
View
6 spec/datetime/allocate_spec.rb
@@ -1,7 +1,7 @@
require File.expand_path('../../spec_helper', __FILE__)
-describe "Date.allocate" do
- it "should not be defined" do
- proc{DateTime.allocate}.should raise_error
+describe "DateTime.allocate" do
+ it "should be the same as jd" do
+ DateTime.allocate.should == DateTime.jd
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.