summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-09-25 18:05:55 +0900
committerKoichi Sasada <ko1@atdot.net>2020-09-25 22:16:55 +0900
commit0096d2b895395df5ab8696d3b6d444dc1b7730b6 (patch)
tree21aa9c7e0eab7304433d05b6bce6f5b26f5e1d95
parentf4328d7f5d035b5a292d00ad21e79818b9220d8b (diff)
freeze all Range objects.v3_0_0_preview1
Matz want to try to freeze all Range objects. [Feature #15504]
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3583
-rw-r--r--NEWS.md4
-rw-r--r--bootstraptest/test_ractor.rb7
-rw-r--r--range.c4
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb2
-rw-r--r--spec/ruby/core/range/initialize_spec.rb9
-rw-r--r--test/ruby/test_array.rb2
-rw-r--r--test/ruby/test_range.rb4
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