Permalink
Browse files

Add support for #dup and #clone, fixes issue #21

  • Loading branch information...
1 parent c4b610f commit a0afad36b86d33a6022ff20ee0602e9395b6da06 @jeremyevans committed Feb 28, 2011
Showing with 160 additions and 0 deletions.
  1. +30 −0 ext/date_ext/date_ext.c
  2. +30 −0 ext/date_ext/datetime.c
  3. +25 −0 spec/date/clone_spec.rb
  4. +25 −0 spec/date/dup_spec.rb
  5. +25 −0 spec/datetime/clone_spec.rb
  6. +25 −0 spec/datetime/dup_spec.rb
@@ -2089,6 +2089,20 @@ static VALUE rhrd_asctime(VALUE self) {
}
/* call-seq:
+ * clone() -> Date
+ *
+ * Returns a clone of the receiver.
+ */
+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);
+ return rd;
+}
+
+/* call-seq:
* cwday() -> Integer
*
* Returns the commercial week day as an +Integer+. Example:
@@ -2202,6 +2216,20 @@ static VALUE rhrd_downto(VALUE self, VALUE other) {
}
/* call-seq:
+ * dup() -> Date
+ *
+ * Returns a dup of the receiver.
+ */
+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);
+ return rd;
+}
+
+/* call-seq:
* eql?(date) -> true or false
*
* Returns true only if the +date+ given is the same date as the receiver.
@@ -4067,12 +4095,14 @@ void Init_date_ext(void) {
rb_define_method(rhrd_class, "_dump", rhrd__dump, 1);
rb_define_method(rhrd_class, "asctime", rhrd_asctime, 0);
+ rb_define_method(rhrd_class, "clone", rhrd_clone, 0);
rb_define_method(rhrd_class, "cwday", rhrd_cwday, 0);
rb_define_method(rhrd_class, "cweek", rhrd_cweek, 0);
rb_define_method(rhrd_class, "cwyear", rhrd_cwyear, 0);
rb_define_method(rhrd_class, "day", rhrd_day, 0);
rb_define_method(rhrd_class, "day_fraction", rhrd_day_fraction, 0);
rb_define_method(rhrd_class, "downto", rhrd_downto, 1);
+ rb_define_method(rhrd_class, "dup", rhrd_dup, 0);
rb_define_method(rhrd_class, "eql?", rhrd_eql_q, 1);
rb_define_method(rhrd_class, "gregorian", rhrd_gregorian, 0);
rb_define_method(rhrd_class, "gregorian?", rhrd_gregorian_q, 0);
@@ -1001,6 +1001,20 @@ static VALUE rhrdt_asctime(VALUE self) {
}
/* call-seq:
+ * clone() -> DateTime
+ *
+ * Returns a clone of the receiver.
+ */
+static VALUE rhrdt_clone(VALUE self) {
+ rhrdt_t *d, *nd;
+ VALUE rd = Data_Make_Struct(rb_obj_class(self), rhrdt_t, NULL, -1, nd);
+ Data_Get_Struct(self, rhrdt_t, d);
+ memcpy(nd, d, sizeof(rhrdt_t));
+ CLONESETUP(rd, self);
+ return rd;
+}
+
+/* call-seq:
* cwday() -> Integer
*
* Returns the commercial week day as an +Integer+. Example:
@@ -1104,6 +1118,20 @@ static VALUE rhrdt_day_fraction(VALUE self) {
}
/* call-seq:
+ * dup() -> DateTime
+ *
+ * Returns a dup of the receiver.
+ */
+static VALUE rhrdt_dup(VALUE self) {
+ rhrdt_t *d, *nd;
+ VALUE rd = Data_Make_Struct(rb_obj_class(self), rhrdt_t, NULL, -1, nd);
+ Data_Get_Struct(self, rhrdt_t, d);
+ memcpy(nd, d, sizeof(rhrdt_t));
+ DUPSETUP(rd, self);
+ return rd;
+}
+
+/* call-seq:
* downto(target){|datetime|} -> DateTime
*
* Equivalent to calling +step+ with the +target+ as the first argument
@@ -2765,12 +2793,14 @@ void Init_datetime(void) {
rb_define_method(rhrdt_class, "ajd", rhrdt_ajd, 0);
rb_define_method(rhrdt_class, "amjd", rhrdt_amjd, 0);
rb_define_method(rhrdt_class, "asctime", rhrdt_asctime, 0);
+ rb_define_method(rhrdt_class, "clone", rhrdt_clone, 0);
rb_define_method(rhrdt_class, "cwday", rhrdt_cwday, 0);
rb_define_method(rhrdt_class, "cweek", rhrdt_cweek, 0);
rb_define_method(rhrdt_class, "cwyear", rhrdt_cwyear, 0);
rb_define_method(rhrdt_class, "day", rhrdt_day, 0);
rb_define_method(rhrdt_class, "day_fraction", rhrdt_day_fraction, 0);
rb_define_method(rhrdt_class, "downto", rhrdt_downto, 1);
+ rb_define_method(rhrdt_class, "dup", rhrdt_dup, 0);
rb_define_method(rhrdt_class, "eql?", rhrdt_eql_q, 1);
rb_define_method(rhrdt_class, "hash", rhrdt_hash, 0);
rb_define_method(rhrdt_class, "hour", rhrdt_hour, 0);
@@ -0,0 +1,25 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+describe "Date#clone" do
+ before do
+ @d = Date.today
+ end
+
+ it "should return a copy of the date" do
+ @d.clone.should == @d
+ end
+
+ it "should return a different object_id" do
+ @d.clone.object_id.should_not == @d.object_id
+ end
+
+ it "should keep frozen status" do
+ @d.freeze
+ @d.clone.frozen?.should be_true
+ end
+
+ it "should keep singleton_methods" do
+ class << @d; def foo() 1 end end
+ @d.clone.respond_to?(:foo).should be_true
+ end
+end
View
@@ -0,0 +1,25 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+describe "Date#dup" do
+ before do
+ @d = Date.today
+ end
+
+ it "should return a copy of the date" do
+ @d.dup.should == @d
+ end
+
+ it "should return a different object_id" do
+ @d.dup.object_id.should_not == @d.object_id
+ end
+
+ it "should not keep frozen status" do
+ @d.freeze
+ @d.dup.frozen?.should be_false
+ end
+
+ it "should not keep singleton_methods" do
+ class << @d; def foo() 1 end end
+ @d.dup.respond_to?(:foo).should be_false
+ end
+end
@@ -0,0 +1,25 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+describe "DateTime#clone" do
+ before do
+ @d = DateTime.now
+ end
+
+ it "should return a copy of the date" do
+ @d.clone.should == @d
+ end
+
+ it "should return a different object_id" do
+ @d.clone.object_id.should_not == @d.object_id
+ end
+
+ it "should keep frozen status" do
+ @d.freeze
+ @d.clone.frozen?.should be_true
+ end
+
+ it "should keep singleton_methods" do
+ class << @d; def foo() 1 end end
+ @d.clone.respond_to?(:foo).should be_true
+ end
+end
@@ -0,0 +1,25 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+describe "DateTime#dup" do
+ before do
+ @d = DateTime.now
+ end
+
+ it "should return a copy of the date" do
+ @d.dup.should == @d
+ end
+
+ it "should return a different object_id" do
+ @d.dup.object_id.should_not == @d.object_id
+ end
+
+ it "should not keep frozen status" do
+ @d.freeze
+ @d.dup.frozen?.should be_false
+ end
+
+ it "should not keep singleton_methods" do
+ class << @d; def foo() 1 end end
+ @d.dup.respond_to?(:foo).should be_false
+ end
+end

0 comments on commit a0afad3

Please sign in to comment.