[前][次][番号順一覧][スレッド一覧]

ruby-changes:45609

From: nobu <ko1@a...>
Date: Wed, 22 Feb 2017 11:02:16 +0900 (JST)
Subject: [ruby-changes:45609] nobu:r57682 (trunk): numeric.c: Numeric#clone and #dup

nobu	2017-02-22 11:02:11 +0900 (Wed, 22 Feb 2017)

  New Revision: 57682

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=57682

  Log:
    numeric.c: Numeric#clone and #dup
    
    * numeric.c (num_clone, num_dup): no longer raises TypeError,
      returns the receiver instead as well as Integer and Float.
      [ruby-core:79636] [Bug #13237]
    
    * object.c (rb_immutable_obj_clone): immutable object clone with
      freeze optional keyword argument.

  Modified files:
    trunk/internal.h
    trunk/numeric.c
    trunk/object.c
    trunk/test/ruby/test_numeric.rb
Index: object.c
===================================================================
--- object.c	(revision 57681)
+++ object.c	(revision 57682)
@@ -309,6 +309,9 @@ special_object_p(VALUE obj) https://github.com/ruby/ruby/blob/trunk/object.c#L309
       case T_BIGNUM:
       case T_FLOAT:
       case T_SYMBOL:
+      case T_RATIONAL:
+      case T_COMPLEX:
+	/* not a comprehensive list */
 	return TRUE;
       default:
 	return FALSE;
@@ -349,6 +352,13 @@ rb_obj_clone2(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/object.c#L352
     return immutable_obj_clone(obj, kwfreeze);
 }
 
+VALUE
+rb_immutable_obj_clone(int argc, VALUE *argv, VALUE obj)
+{
+    int kwfreeze = freeze_opt(argc, argv);
+    return immutable_obj_clone(obj, kwfreeze);
+}
+
 static int
 freeze_opt(int argc, VALUE *argv)
 {
Index: test/ruby/test_numeric.rb
===================================================================
--- test/ruby/test_numeric.rb	(revision 57681)
+++ test/ruby/test_numeric.rb	(revision 57682)
@@ -76,12 +76,18 @@ class TestNumeric < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_numeric.rb#L76
 
   def test_dup
     a = Numeric.new
-    assert_raise(TypeError) { a.dup }
+    assert_same a, a.dup
+  end
+
+  def test_clone
+    a = Numeric.new
+    assert_same a, a.clone
+    assert_raise(ArgumentError) {a.clone(freeze: false)}
 
-    c = Module.new do
-      break eval("class C\u{3042} < Numeric; self; end")
+    c = EnvUtil.labeled_class("\u{1f4a9}", Numeric)
+    assert_raise_with_message(ArgumentError, /\u{1f4a9}/) do
+      c.new.clone(freeze: false)
     end
-    assert_raise_with_message(TypeError, /C\u3042/) {c.new.dup}
   end
 
   def test_quo
Index: internal.h
===================================================================
--- internal.h	(revision 57681)
+++ internal.h	(revision 57682)
@@ -1363,6 +1363,7 @@ VALUE rb_class_search_ancestor(VALUE kla https://github.com/ruby/ruby/blob/trunk/internal.h#L1363
 NORETURN(void rb_undefined_alloc(VALUE klass));
 double rb_num_to_dbl(VALUE val);
 VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
+VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
 
 struct RBasicRaw {
     VALUE flags;
Index: numeric.c
===================================================================
--- numeric.c	(revision 57681)
+++ numeric.c	(revision 57682)
@@ -552,18 +552,38 @@ num_sadded(VALUE x, VALUE name) https://github.com/ruby/ruby/blob/trunk/numeric.c#L552
     UNREACHABLE;
 }
 
+#if 0
 /*
- * Numerics are immutable values, which should not be copied.
+ *  call-seq:
+ *     num.clone(freeze: true) -> num
  *
- * Any attempt to use this method on a Numeric will raise a TypeError.
+ *  Returns the receiver.
+ *  _freeze_ cannot be +false+.
  */
 static VALUE
-num_init_copy(VALUE x, VALUE y)
+num_clone(int argc, VALUE *argv, VALUE x)
 {
-    rb_raise(rb_eTypeError, "can't copy %"PRIsVALUE, rb_obj_class(x));
+    return rb_immutable_obj_clone(argc, argv, x);
+}
+#else
+# define num_clone rb_immutable_obj_clone
+#endif
 
-    UNREACHABLE;
+#if 0
+/*
+ *  call-seq:
+ *     num.dup -> num
+ *
+ *  Returns the receiver.
+ */
+static VALUE
+num_dup(VALUE x)
+{
+    return x;
 }
+#else
+# define num_dup num_uplus
+#endif
 
 /*
  *  call-seq:
@@ -5222,8 +5242,9 @@ Init_Numeric(void) https://github.com/ruby/ruby/blob/trunk/numeric.c#L5242
 
     rb_define_method(rb_cNumeric, "singleton_method_added", num_sadded, 1);
     rb_include_module(rb_cNumeric, rb_mComparable);
-    rb_define_method(rb_cNumeric, "initialize_copy", num_init_copy, 1);
     rb_define_method(rb_cNumeric, "coerce", num_coerce, 1);
+    rb_define_method(rb_cNumeric, "clone", num_clone, -1);
+    rb_define_method(rb_cNumeric, "dup", num_dup, 0);
 
     rb_define_method(rb_cNumeric, "i", num_imaginary, 0);
     rb_define_method(rb_cNumeric, "+@", num_uplus, 0);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]