1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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]
This commit is contained in:
Jeremy Evans 2019-08-07 09:01:33 -07:00
parent 7470f96565
commit 2e551356a7
Notes: git 2019-09-22 08:11:08 +09:00
6 changed files with 23 additions and 0 deletions

View file

@ -563,6 +563,9 @@ nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
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);
}

View file

@ -2722,6 +2722,9 @@ f_BigDecimal(int argc, VALUE *argv, VALUE self)
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;

View file

@ -1323,6 +1323,8 @@ path_unlink(VALUE self)
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);
}

View file

@ -54,6 +54,11 @@ class TestBigDecimal < Test::Unit::TestCase
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") }

View file

@ -471,6 +471,12 @@ class TestPathname < Test::Unit::TestCase
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

View file

@ -123,6 +123,10 @@ class Complex_Test < Test::Unit::TestCase
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)}