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

[Bug #17767] Now ENV.clone raises TypeError as well as ENV.dup

One year ago, the former method has been deprecated while the latter
has become an error.  Then the 3.1 released, it is enough time to make
also the former an error.
This commit is contained in:
Nobuyoshi Nakada 2022-07-20 19:19:23 +09:00
parent 3e4fedca4e
commit ec3f59309e
Notes: git 2022-08-02 16:40:37 +09:00
2 changed files with 14 additions and 55 deletions

21
hash.c
View file

@ -6639,31 +6639,26 @@ env_update(int argc, VALUE *argv, VALUE env)
return env; return env;
} }
NORETURN(static VALUE env_clone(int, VALUE *, VALUE));
/* /*
* call-seq: * call-seq:
* ENV.clone(freeze: nil) -> ENV * ENV.clone(freeze: nil) # raises TypeError
* *
* Returns ENV itself, and warns because ENV is a wrapper for the * Raises TypeError, because ENV is a wrapper for the process-wide
* process-wide environment variables and a clone is useless. * environment variables and a clone is useless.
* If +freeze+ keyword is given and not +nil+ or +false+, raises ArgumentError. * Use #to_h to get a copy of ENV data as a hash.
* If +freeze+ keyword is given and +true+, raises TypeError, as ENV storage
* cannot be frozen.
*/ */
static VALUE static VALUE
env_clone(int argc, VALUE *argv, VALUE obj) env_clone(int argc, VALUE *argv, VALUE obj)
{ {
if (argc) { if (argc) {
VALUE opt, kwfreeze; VALUE opt;
if (rb_scan_args(argc, argv, "0:", &opt) < argc) { if (rb_scan_args(argc, argv, "0:", &opt) < argc) {
kwfreeze = rb_get_freeze_opt(1, &opt); rb_get_freeze_opt(1, &opt);
if (RTEST(kwfreeze)) {
rb_raise(rb_eTypeError, "cannot freeze ENV");
}
} }
} }
rb_warn_deprecated("ENV.clone", "ENV.to_h"); rb_raise(rb_eTypeError, "Cannot clone ENV, use ENV.to_h to get a copy of ENV as a hash");
return envtbl;
} }
NORETURN(static VALUE env_dup(VALUE)); NORETURN(static VALUE env_dup(VALUE));

View file

@ -69,25 +69,20 @@ class TestEnv < Test::Unit::TestCase
end end
def test_clone def test_clone
warning = /ENV\.clone is deprecated; use ENV\.to_h instead/ message = /Cannot clone ENV/
clone = assert_deprecated_warning(warning) { assert_raise_with_message(TypeError, message) {
ENV.clone ENV.clone
} }
assert_same(ENV, clone) assert_raise_with_message(TypeError, message) {
clone = assert_deprecated_warning(warning) {
ENV.clone(freeze: false) ENV.clone(freeze: false)
} }
assert_same(ENV, clone) assert_raise_with_message(TypeError, message) {
clone = assert_deprecated_warning(warning) {
ENV.clone(freeze: nil) ENV.clone(freeze: nil)
} }
assert_same(ENV, clone) assert_raise_with_message(TypeError, message) {
assert_raise(TypeError) {
ENV.clone(freeze: true) ENV.clone(freeze: true)
} }
assert_raise(ArgumentError) { assert_raise(ArgumentError) {
ENV.clone(freeze: 1) ENV.clone(freeze: 1)
} }
@ -688,37 +683,6 @@ class TestEnv < Test::Unit::TestCase
end; end;
end end
def test_clone_in_ractor
assert_ractor(<<-"end;")
r = Ractor.new do
original_warning_state = Warning[:deprecated]
Warning[:deprecated] = false
begin
Ractor.yield ENV.clone.object_id
Ractor.yield ENV.clone(freeze: false).object_id
Ractor.yield ENV.clone(freeze: nil).object_id
#{str_for_yielding_exception_class("ENV.clone(freeze: true)")}
#{str_for_yielding_exception_class("ENV.clone(freeze: 1)")}
#{str_for_yielding_exception_class("ENV.clone(foo: false)")}
#{str_for_yielding_exception_class("ENV.clone(1)")}
#{str_for_yielding_exception_class("ENV.clone(1, foo: false)")}
ensure
Warning[:deprecated] = original_warning_state
end
end
assert_equal(ENV.object_id, r.take)
assert_equal(ENV.object_id, r.take)
assert_equal(ENV.object_id, r.take)
#{str_for_assert_raise_on_yielded_exception_class(TypeError, "r")}
4.times do
#{str_for_assert_raise_on_yielded_exception_class(ArgumentError, "r")}
end
end;
end
def test_has_value_in_ractor def test_has_value_in_ractor
assert_ractor(<<-"end;") assert_ractor(<<-"end;")
r = Ractor.new do r = Ractor.new do