From 0096d2b895395df5ab8696d3b6d444dc1b7730b6 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 25 Sep 2020 18:05:55 +0900 Subject: freeze all Range objects. Matz want to try to freeze all Range objects. [Feature #15504] --- NEWS.md | 4 ++++ bootstraptest/test_ractor.rb | 7 +++---- range.c | 4 ++++ spec/ruby/core/marshal/dump_spec.rb | 2 +- spec/ruby/core/range/initialize_spec.rb | 9 +++++++-- test/ruby/test_array.rb | 2 +- test/ruby/test_range.rb | 4 ++-- 7 files changed, 22 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9a74c719c7..fe8e9df799 100644 --- a/NEWS.md +++ b/NEWS.md @@ -163,6 +163,10 @@ Outstanding ones only. p C.ancestors #=> [C, M1, M2, Object, Kernel, BasicObject] ``` +* Range + + * All Range objects are frozen. [Feature #15504] + * Thread * Introduce `Thread#scheduler` for intercepting blocking operations and diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index a71f00672b..6f94ce6918 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -448,9 +448,9 @@ assert_equal "ok", %q{ [{a: 1}.freeze, 'str'.freeze].freeze, # nested frozen container S.new(1, 2).freeze, # frozen Struct S.new(1, 2, 3, 4).freeze, # frozen Struct - (1..2).freeze, # Range on Struct - (1..).freeze, # Range on Strcut - (..1).freeze, # Range on Strcut + (1..2), # Range on Struct + (1..), # Range on Strcut + (..1), # Range on Strcut C, # class M, # module Ractor.current, # Ractor @@ -463,7 +463,6 @@ assert_equal "ok", %q{ S.new(1, 2), S.new(1, 2, 3, 4), S.new("a", 2).freeze, # frozen, but refers to an unshareable object - (1..2), (1..), (..1), ] results = [] diff --git a/range.c b/range.c index 224e5d3336..17d29925f1 100644 --- a/range.c +++ b/range.c @@ -58,6 +58,10 @@ range_init(VALUE range, VALUE beg, VALUE end, VALUE exclude_end) RANGE_SET_EXCL(range, exclude_end); RANGE_SET_BEG(range, beg); RANGE_SET_END(range, end); + + if (CLASS_OF(range) == rb_cRange) { + rb_obj_freeze(range); + } } VALUE diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb index 4ffc586364..30f1b7513b 100644 --- a/spec/ruby/core/marshal/dump_spec.rb +++ b/spec/ruby/core/marshal/dump_spec.rb @@ -419,7 +419,7 @@ describe "Marshal.dump" do load.should == range load.instance_variable_get(:@foo).should == 42 end - end + end unless (1...3).frozen? # Ruby 3.0 - describe "with a Time" do before :each do diff --git a/spec/ruby/core/range/initialize_spec.rb b/spec/ruby/core/range/initialize_spec.rb index 8caf12baa2..d2826a5ba5 100644 --- a/spec/ruby/core/range/initialize_spec.rb +++ b/spec/ruby/core/range/initialize_spec.rb @@ -28,8 +28,13 @@ describe "Range#initialize" do end it "raises a NameError if called on an already initialized Range" do - -> { (0..1).send(:initialize, 1, 3) }.should raise_error(NameError) - -> { (0..1).send(:initialize, 1, 3, true) }.should raise_error(NameError) + if (0..1).frozen? # Ruby 3.0- + -> { (0..1).send(:initialize, 1, 3) }.should raise_error(FrozenError) + -> { (0..1).send(:initialize, 1, 3, true) }.should raise_error(FrozenError) + else + -> { (0..1).send(:initialize, 1, 3) }.should raise_error(NameError) + -> { (0..1).send(:initialize, 1, 3, true) }.should raise_error(NameError) + end end it "raises an ArgumentError if arguments don't respond to <=>" do diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 9e36e74e71..64bcf9f1aa 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -2612,7 +2612,7 @@ class TestArray < Test::Unit::TestCase def test_zip_bug bug8153 = "ruby-core:53650" - r = 1..1 + r = [1] def r.respond_to?(*) super end diff --git a/test/ruby/test_range.rb b/test/ruby/test_range.rb index 9c8bbaf239..ba9b81ecc7 100644 --- a/test/ruby/test_range.rb +++ b/test/ruby/test_range.rb @@ -163,8 +163,8 @@ class TestRange < Test::Unit::TestCase def test_initialize_twice r = eval("1..2") - assert_raise(NameError) { r.instance_eval { initialize 3, 4 } } - assert_raise(NameError) { r.instance_eval { initialize_copy 3..4 } } + assert_raise(FrozenError) { r.instance_eval { initialize 3, 4 } } + assert_raise(FrozenError) { r.instance_eval { initialize_copy 3..4 } } end def test_uninitialized_range -- cgit v1.2.3