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

ruby-changes:57856

From: Jeremy <ko1@a...>
Date: Sun, 22 Sep 2019 08:10:51 +0900 (JST)
Subject: [ruby-changes:57856] 2e551356a7 (master): Make Kernel#{Pathname, BigDecimal, Complex} return argument if given correct type

https://git.ruby-lang.org/ruby.git/commit/?id=2e551356a7

From 2e551356a7a6e74ba07283e000ff16f5d1ea6506 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Wed, 7 Aug 2019 09:01:33 -0700
Subject: Make Kernel#{Pathname,BigDecimal,Complex} return argument if given
 correct type

This is how Kernel#{Array,String,Float,Integer,Hash,Rational} work.
BigDecimal and Complex instances are always frozen, so this should
not cause backwards compatibility issues for those.  Pathname
instances are not frozen, so potentially this could cause backwards
compatibility issues by not returning a new object.

Based on a patch from Joshua Ballanco, some minor changes by me.

Fixes [Bug #7522]

diff --git a/complex.c b/complex.c
index ec60c00..144a59d 100644
--- a/complex.c
+++ b/complex.c
@@ -563,6 +563,9 @@ nucomp_f_complex(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/complex.c#L563
     if (!NIL_P(opts)) {
         raise = rb_opts_exception_p(opts, raise);
     }
+    if (argc > 0 && CLASS_OF(a1) == rb_cComplex && a2 == Qundef) {
+        return a1;
+    }
     return nucomp_convert(rb_cComplex, a1, a2, raise);
 }
 
diff --git a/ext/bigdecimal/bigdecimal.c b/ext/bigdecimal/bigdecimal.c
index 652f341..6d50475 100644
--- a/ext/bigdecimal/bigdecimal.c
+++ b/ext/bigdecimal/bigdecimal.c
@@ -2722,6 +2722,9 @@ f_BigDecimal(int argc, VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/bigdecimal/bigdecimal.c#L2722
     Real *pv;
     VALUE obj;
 
+    if (argc > 0 && CLASS_OF(argv[0]) == rb_cBigDecimal) {
+        if (argc == 1 || (argc == 2 && RB_TYPE_P(argv[1], T_HASH))) return argv[0];
+    }
     obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
     pv = BigDecimal_new(argc, argv);
     if (pv == NULL) return Qnil;
diff --git a/ext/pathname/pathname.c b/ext/pathname/pathname.c
index 70f8258..1cf0f90 100644
--- a/ext/pathname/pathname.c
+++ b/ext/pathname/pathname.c
@@ -1323,6 +1323,8 @@ path_unlink(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/pathname/pathname.c#L1323
 static VALUE
 path_f_pathname(VALUE self, VALUE str)
 {
+    if (CLASS_OF(str) == rb_cPathname)
+        return str;
     return rb_class_new_instance(1, &str, rb_cPathname);
 }
 
diff --git a/test/bigdecimal/test_bigdecimal.rb b/test/bigdecimal/test_bigdecimal.rb
index e4f1444..b3368b4 100644
--- a/test/bigdecimal/test_bigdecimal.rb
+++ b/test/bigdecimal/test_bigdecimal.rb
@@ -54,6 +54,11 @@ class TestBigDecimal < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/bigdecimal/test_bigdecimal.rb#L54
     assert_equal(111, BigDecimal("1_1_1_"))
     assert_equal(10**(-1), BigDecimal("1E-1"), '#4825')
     assert_equal(1234, BigDecimal(" \t\n\r \r1234 \t\n\r \r"))
+    bd = BigDecimal.new("1.12", 1)
+    assert_same(bd, BigDecimal(bd))
+    assert_same(bd, BigDecimal(bd, exception: false))
+    assert_not_same(bd, BigDecimal(bd, 1))
+    assert_not_same(bd, BigDecimal(bd, 1, exception: false))
 
     assert_raise(ArgumentError) { BigDecimal("1", -1) }
     assert_raise_with_message(ArgumentError, /"1__1_1"/) { BigDecimal("1__1_1") }
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index eaecc52..af523f9 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -471,6 +471,12 @@ class TestPathname < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/pathname/test_pathname.rb#L471
     assert_raise(ArgumentError) { Pathname.new("a\0") }
   end
 
+  def test_global_constructor
+    p = Pathname.new('a')
+    assert_equal(p, Pathname('a'))
+    assert_same(p, Pathname(p))
+  end
+
   class AnotherStringLike # :nodoc:
     def initialize(s) @s = s end
     def to_str() @s end
diff --git a/test/ruby/test_complex.rb b/test/ruby/test_complex.rb
index 2a72f3b..a4fe9d4 100644
--- a/test/ruby/test_complex.rb
+++ b/test/ruby/test_complex.rb
@@ -123,6 +123,10 @@ class Complex_Test < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_complex.rb#L123
     assert_raise(TypeError){Complex(Object.new)}
     assert_raise(ArgumentError){Complex()}
     assert_raise(ArgumentError){Complex(1,2,3)}
+    c = Complex(1,0)
+    assert_same(c, Complex(c))
+    assert_same(c, Complex(c, exception: false))
+    assert_raise(ArgumentError){Complex(c, bad_keyword: true)}
 
     if (0.0/0).nan?
       assert_nothing_raised{Complex(0.0/0)}
-- 
cgit v0.10.2


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

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