diff --git a/error.c b/error.c
index f00951940f..d257028ad2 100644
--- a/error.c
+++ b/error.c
@@ -804,6 +804,7 @@ VALUE rb_eSignal;
VALUE rb_eFatal;
VALUE rb_eStandardError;
VALUE rb_eRuntimeError;
+VALUE rb_eFrozenError;
VALUE rb_eTypeError;
VALUE rb_eArgError;
VALUE rb_eIndexError;
@@ -2011,16 +2012,21 @@ syserr_eqq(VALUE self, VALUE exc)
*/
/*
- * Document-class: RuntimeError
+ * Document-class: FrozenError
*
- * A generic error class raised when an invalid operation is attempted.
+ * Raised when there is an attempt to modify a frozen object.
*
* [1, 2, 3].freeze << 4
*
* raises the exception:
*
- * RuntimeError: can't modify frozen Array
+ * FrozenError: can't modify frozen Array
+ */
+
+/*
+ * Document-class: RuntimeError
*
+ * A generic error class raised when an invalid operation is attempted.
* Kernel#raise will raise a RuntimeError if no Exception class is
* specified.
*
@@ -2233,6 +2239,7 @@ Init_Exception(void)
rb_define_method(rb_eNoMethodError, "private_call?", nometh_err_private_call_p, 0);
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
+ rb_eFrozenError = rb_define_class("FrozenError", rb_eRuntimeError);
rb_eSecurityError = rb_define_class("SecurityError", rb_eException);
rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException);
rb_eEncodingError = rb_define_class("EncodingError", rb_eStandardError);
@@ -2588,7 +2595,7 @@ rb_load_fail(VALUE path, const char *err)
void
rb_error_frozen(const char *what)
{
- rb_raise(rb_eRuntimeError, "can't modify frozen %s", what);
+ rb_raise(rb_eFrozenError, "can't modify frozen %s", what);
}
void
@@ -2601,11 +2608,11 @@ rb_error_frozen_object(VALUE frozen_obj)
VALUE path = rb_ary_entry(debug_info, 0);
VALUE line = rb_ary_entry(debug_info, 1);
- rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
+ rb_raise(rb_eFrozenError, "can't modify frozen %"PRIsVALUE", created at %"PRIsVALUE":%"PRIsVALUE,
CLASS_OF(frozen_obj), path, line);
}
else {
- rb_raise(rb_eRuntimeError, "can't modify frozen %"PRIsVALUE,
+ rb_raise(rb_eFrozenError, "can't modify frozen %"PRIsVALUE,
CLASS_OF(frozen_obj));
}
}
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 8745fb903a..9c7d2fb684 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1946,6 +1946,7 @@ RUBY_EXTERN VALUE rb_eKeyError;
RUBY_EXTERN VALUE rb_eRangeError;
RUBY_EXTERN VALUE rb_eIOError;
RUBY_EXTERN VALUE rb_eRuntimeError;
+RUBY_EXTERN VALUE rb_eFrozenError;
RUBY_EXTERN VALUE rb_eSecurityError;
RUBY_EXTERN VALUE rb_eSystemCallError;
RUBY_EXTERN VALUE rb_eThreadError;
diff --git a/object.c b/object.c
index c417141a67..adec3f5e76 100644
--- a/object.c
+++ b/object.c
@@ -1315,7 +1315,7 @@ rb_obj_infect(VALUE victim, VALUE carrier)
*
* produces:
*
- * prog.rb:3:in `<<': can't modify frozen Array (RuntimeError)
+ * prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
* from prog.rb:3
*
* Objects of the following classes are always frozen: Integer,
diff --git a/test/-ext-/string/test_enc_associate.rb b/test/-ext-/string/test_enc_associate.rb
index 4fad8e1cc8..95d1f00cd2 100644
--- a/test/-ext-/string/test_enc_associate.rb
+++ b/test/-ext-/string/test_enc_associate.rb
@@ -7,8 +7,8 @@ class Test_StrEncAssociate < Test::Unit::TestCase
s = Bug::String.new("abc")
s.force_encoding(Encoding::US_ASCII)
s.freeze
- assert_raise(RuntimeError) {s.associate_encoding!(Encoding::US_ASCII)}
- assert_raise(RuntimeError) {s.associate_encoding!(Encoding::UTF_8)}
+ assert_raise(FrozenError) {s.associate_encoding!(Encoding::US_ASCII)}
+ assert_raise(FrozenError) {s.associate_encoding!(Encoding::UTF_8)}
end
Encoding.list.select(&:dummy?).each do |enc|
diff --git a/test/date/test_date_marshal.rb b/test/date/test_date_marshal.rb
index 10e396b71b..99a7239f95 100644
--- a/test/date/test_date_marshal.rb
+++ b/test/date/test_date_marshal.rb
@@ -30,13 +30,13 @@ class TestDateMarshal < Test::Unit::TestCase
a = d.marshal_dump
d.freeze
assert(d.frozen?)
- assert_raise(RuntimeError){d.marshal_load(a)}
+ assert_raise(FrozenError){d.marshal_load(a)}
d = DateTime.now
a = d.marshal_dump
d.freeze
assert(d.frozen?)
- assert_raise(RuntimeError){d.marshal_load(a)}
+ assert_raise(FrozenError){d.marshal_load(a)}
end
end
diff --git a/test/dbm/test_dbm.rb b/test/dbm/test_dbm.rb
index 0812b4023f..93198fdea2 100644
--- a/test/dbm/test_dbm.rb
+++ b/test/dbm/test_dbm.rb
@@ -625,7 +625,7 @@ if defined? DBM
def test_freeze
DBM.open("#{@tmproot}/a") {|d|
d.freeze
- assert_raise(RuntimeError) { d["k"] = "v" }
+ assert_raise(FrozenError) { d["k"] = "v" }
}
end
end
diff --git a/test/gdbm/test_gdbm.rb b/test/gdbm/test_gdbm.rb
index 9a9dc28972..1d69634f88 100644
--- a/test/gdbm/test_gdbm.rb
+++ b/test/gdbm/test_gdbm.rb
@@ -722,7 +722,7 @@ if defined? GDBM
def test_freeze
GDBM.open("#{@tmproot}/a.dbm") {|d|
d.freeze
- assert_raise(RuntimeError) { d["k"] = "v" }
+ assert_raise(FrozenError) { d["k"] = "v" }
}
end
end
diff --git a/test/pathname/test_pathname.rb b/test/pathname/test_pathname.rb
index 5007ebac22..ad104d06df 100644
--- a/test/pathname/test_pathname.rb
+++ b/test/pathname/test_pathname.rb
@@ -635,7 +635,7 @@ class TestPathname < Test::Unit::TestCase
obj = Pathname.new("a")
obj.freeze
assert_equal(false, obj.tainted?)
- assert_raise(RuntimeError) { obj.taint }
+ assert_raise(FrozenError) { obj.taint }
obj = Pathname.new("a")
obj.taint
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 508312e4a2..7e63623b7d 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -601,7 +601,7 @@ class TestArray < Test::Unit::TestCase
assert_equal([4, 5, 4, 5, 4, 5], b)
assert_raise(TypeError) { [0].concat(:foo) }
- assert_raise(RuntimeError) { [0].freeze.concat(:foo) }
+ assert_raise(FrozenError) { [0].freeze.concat(:foo) }
end
def test_count
@@ -1299,10 +1299,10 @@ class TestArray < Test::Unit::TestCase
fa = a.dup.freeze
assert_nothing_raised(RuntimeError) { a.replace(a) }
- assert_raise(RuntimeError) { fa.replace(fa) }
+ assert_raise(FrozenError) { fa.replace(fa) }
assert_raise(ArgumentError) { fa.replace() }
assert_raise(TypeError) { a.replace(42) }
- assert_raise(RuntimeError) { fa.replace(42) }
+ assert_raise(FrozenError) { fa.replace(42) }
end
def test_reverse
@@ -1530,7 +1530,7 @@ class TestArray < Test::Unit::TestCase
o2 = o1.clone
ary << o1 << o2
orig = ary.dup
- assert_raise(RuntimeError, "frozen during comparison") {ary.sort!}
+ assert_raise(FrozenError, "frozen during comparison") {ary.sort!}
assert_equal(orig, ary, "must not be modified once frozen")
end
@@ -1762,7 +1762,7 @@ class TestArray < Test::Unit::TestCase
f = a.dup.freeze
assert_raise(ArgumentError) { a.uniq!(1) }
assert_raise(ArgumentError) { f.uniq!(1) }
- assert_raise(RuntimeError) { f.uniq! }
+ assert_raise(FrozenError) { f.uniq! }
assert_nothing_raised do
a = [ {c: "b"}, {c: "r"}, {c: "w"}, {c: "g"}, {c: "g"} ]
@@ -1808,7 +1808,7 @@ class TestArray < Test::Unit::TestCase
def test_uniq_bang_with_freeze
ary = [1,2]
orig = ary.dup
- assert_raise(RuntimeError, "frozen during comparison") {
+ assert_raise(FrozenError, "frozen during comparison") {
ary.uniq! {|v| ary.freeze; 1}
}
assert_equal(orig, ary, "must not be modified once frozen")
@@ -2121,7 +2121,7 @@ class TestArray < Test::Unit::TestCase
assert_raise(ArgumentError) { [0][0, 0, 0] = 0 }
assert_raise(ArgumentError) { [0].freeze[0, 0, 0] = 0 }
assert_raise(TypeError) { [0][:foo] = 0 }
- assert_raise(RuntimeError) { [0].freeze[:foo] = 0 }
+ assert_raise(FrozenError) { [0].freeze[:foo] = 0 }
end
def test_first2
@@ -2146,8 +2146,8 @@ class TestArray < Test::Unit::TestCase
end
def test_unshift_error
- assert_raise(RuntimeError) { [].freeze.unshift('cat') }
- assert_raise(RuntimeError) { [].freeze.unshift() }
+ assert_raise(FrozenError) { [].freeze.unshift('cat') }
+ assert_raise(FrozenError) { [].freeze.unshift() }
end
def test_aref
@@ -2208,7 +2208,7 @@ class TestArray < Test::Unit::TestCase
assert_equal([0, 1, 2], a.insert(-1, 2))
assert_equal([0, 1, 3, 2], a.insert(-2, 3))
assert_raise_with_message(IndexError, /-6/) { a.insert(-6, 4) }
- assert_raise(RuntimeError) { [0].freeze.insert(0)}
+ assert_raise(FrozenError) { [0].freeze.insert(0)}
assert_raise(ArgumentError) { [0].freeze.insert }
end
@@ -2389,8 +2389,8 @@ class TestArray < Test::Unit::TestCase
assert_raise(ArgumentError) { a.flatten!(1, 2) }
assert_raise(TypeError) { a.flatten!(:foo) }
assert_raise(ArgumentError) { f.flatten!(1, 2) }
- assert_raise(RuntimeError) { f.flatten! }
- assert_raise(RuntimeError) { f.flatten!(:foo) }
+ assert_raise(FrozenError) { f.flatten! }
+ assert_raise(FrozenError) { f.flatten!(:foo) }
end
def test_shuffle
@@ -2728,7 +2728,7 @@ class TestArray < Test::Unit::TestCase
assert_equal([], a.rotate!(13))
assert_equal([], a.rotate!(-13))
a = [].freeze
- assert_raise_with_message(RuntimeError, /can\'t modify frozen/) {a.rotate!}
+ assert_raise_with_message(FrozenError, /can\'t modify frozen/) {a.rotate!}
a = [1,2,3]
assert_raise(ArgumentError) { a.rotate!(1, 1) }
end
diff --git a/test/ruby/test_class.rb b/test/ruby/test_class.rb
index bb8a3c574d..ad2caeb8be 100644
--- a/test/ruby/test_class.rb
+++ b/test/ruby/test_class.rb
@@ -443,14 +443,14 @@ class TestClass < Test::Unit::TestCase
obj = Object.new
c = obj.singleton_class
obj.freeze
- assert_raise_with_message(RuntimeError, /frozen object/) {
+ assert_raise_with_message(FrozenError, /frozen object/) {
c.class_eval {def f; end}
}
end
def test_singleton_class_message
c = Class.new.freeze
- assert_raise_with_message(RuntimeError, /frozen Class/) {
+ assert_raise_with_message(FrozenError, /frozen Class/) {
def c.f; end
}
end
diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb
index 51f69be37d..235dfbfc9b 100644
--- a/test/ruby/test_enumerator.rb
+++ b/test/ruby/test_enumerator.rb
@@ -79,7 +79,7 @@ class TestEnumerator < Test::Unit::TestCase
enum = @obj.to_enum
assert_raise(NoMethodError) { enum.each {} }
enum.freeze
- assert_raise(RuntimeError) {
+ assert_raise(FrozenError) {
capture_io do
# warning: Enumerator.new without a block is deprecated; use Object#to_enum
enum.__send__(:initialize, @obj, :foo)
@@ -440,7 +440,7 @@ class TestEnumerator < Test::Unit::TestCase
assert_equal([1, 2, 3], a)
g.freeze
- assert_raise(RuntimeError) {
+ assert_raise(FrozenError) {
g.__send__ :initialize, proc { |y| y << 4 << 5 }
}
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index 9f25b771bf..0bc0390d64 100644
--- a/test/ruby/test_eval.rb
+++ b/test/ruby/test_eval.rb
@@ -506,7 +506,7 @@ class TestEval < Test::Unit::TestCase
def test_fstring_instance_eval
bug = "[ruby-core:78116] [Bug #12930]".freeze
assert_same bug, (bug.instance_eval {self})
- assert_raise(RuntimeError) {
+ assert_raise(FrozenError) {
bug.instance_eval {@ivar = true}
}
end
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index 813afaeee0..ea19ba80a7 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -1031,8 +1031,8 @@ class TestHash < Test::Unit::TestCase
assert_raise(TypeError) { h2.replace(1) }
h2.freeze
assert_raise(ArgumentError) { h2.replace() }
- assert_raise(RuntimeError) { h2.replace(h1) }
- assert_raise(RuntimeError) { h2.replace(42) }
+ assert_raise(FrozenError) { h2.replace(h1) }
+ assert_raise(FrozenError) { h2.replace(42) }
end
def test_size2
diff --git a/test/ruby/test_lazy_enumerator.rb b/test/ruby/test_lazy_enumerator.rb
index 56890f4b6e..22028283ce 100644
--- a/test/ruby/test_lazy_enumerator.rb
+++ b/test/ruby/test_lazy_enumerator.rb
@@ -32,7 +32,7 @@ class TestLazyEnumerator < Test::Unit::TestCase
a = [1, 2, 3].lazy
a.freeze
- assert_raise(RuntimeError) {
+ assert_raise(FrozenError) {
a.__send__ :initialize, [4, 5], &->(y, *v) { y << yield(*v) }
}
end
diff --git a/test/ruby/test_literal.rb b/test/ruby/test_literal.rb
index 67a383bc3c..cf1a2babd7 100644
--- a/test/ruby/test_literal.rb
+++ b/test/ruby/test_literal.rb
@@ -185,7 +185,7 @@ class TestRubyLiteral < Test::Unit::TestCase
str = RubyVM::InstructionSequence.compile(src, f, f, n, opt).eval
assert_equal("foo-1", str)
assert_predicate(str, :frozen?)
- assert_raise_with_message(RuntimeError, /created at #{Regexp.quote(f)}:#{n}/) {
+ assert_raise_with_message(FrozenError, /created at #{Regexp.quote(f)}:#{n}/) {
str << "x"
}
end
diff --git a/test/ruby/test_marshal.rb b/test/ruby/test_marshal.rb
index 48a7d03428..80ec0b1684 100644
--- a/test/ruby/test_marshal.rb
+++ b/test/ruby/test_marshal.rb
@@ -568,7 +568,7 @@ class TestMarshal < Test::Unit::TestCase
s.instance_variable_set(:@t, 42)
t = Bug8276.new(s)
s = Marshal.dump(t)
- assert_raise(RuntimeError) {Marshal.load(s)}
+ assert_raise(FrozenError) {Marshal.load(s)}
end
def test_marshal_load_ivar
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index d3e08a1fbb..9980844eb4 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -636,15 +636,15 @@ class TestModule < Test::Unit::TestCase
def bar; end
end
m.freeze
- assert_raise(RuntimeError) do
+ assert_raise(FrozenError) do
m.module_eval do
def foo; end
end
end
- assert_raise(RuntimeError) do
+ assert_raise(FrozenError) do
m.__send__ :private, :bar
end
- assert_raise(RuntimeError) do
+ assert_raise(FrozenError) do
m.private_class_method :baz
end
end
@@ -949,7 +949,7 @@ class TestModule < Test::Unit::TestCase
def test_frozen_module
m = Module.new
m.freeze
- assert_raise(RuntimeError) do
+ assert_raise(FrozenError) do
m.instance_eval { undef_method(:foo) }
end
end
@@ -957,7 +957,7 @@ class TestModule < Test::Unit::TestCase
def test_frozen_class
c = Class.new
c.freeze
- assert_raise(RuntimeError) do
+ assert_raise(FrozenError) do
c.instance_eval { undef_method(:foo) }
end
end
@@ -967,7 +967,7 @@ class TestModule < Test::Unit::TestCase
o = klass.new
c = class << o; self; end
c.freeze
- assert_raise_with_message(RuntimeError, /frozen/) do
+ assert_raise_with_message(FrozenError, /frozen/) do
c.instance_eval { undef_method(:foo) }
end
klass.class_eval do
@@ -2077,17 +2077,17 @@ class TestModule < Test::Unit::TestCase
bug11532 = '[ruby-core:70828] [Bug #11532]'
c = Class.new {const_set(:A, 1)}.freeze
- assert_raise_with_message(RuntimeError, /frozen class/, bug11532) {
+ assert_raise_with_message(FrozenError, /frozen class/, bug11532) {
c.class_eval {private_constant :A}
}
c = Class.new {const_set(:A, 1); private_constant :A}.freeze
- assert_raise_with_message(RuntimeError, /frozen class/, bug11532) {
+ assert_raise_with_message(FrozenError, /frozen class/, bug11532) {
c.class_eval {public_constant :A}
}
c = Class.new {const_set(:A, 1)}.freeze
- assert_raise_with_message(RuntimeError, /frozen class/, bug11532) {
+ assert_raise_with_message(FrozenError, /frozen class/, bug11532) {
c.class_eval {deprecate_constant :A}
}
end
diff --git a/test/ruby/test_object.rb b/test/ruby/test_object.rb
index e55a09dc23..c25dcf9c37 100644
--- a/test/ruby/test_object.rb
+++ b/test/ruby/test_object.rb
@@ -99,12 +99,12 @@ class TestObject < Test::Unit::TestCase
def test_taint_frozen_obj
o = Object.new
o.freeze
- assert_raise(RuntimeError) { o.taint }
+ assert_raise(FrozenError) { o.taint }
o = Object.new
o.taint
o.freeze
- assert_raise(RuntimeError) { o.untaint }
+ assert_raise(FrozenError) { o.untaint }
end
def test_freeze_immediate
@@ -123,7 +123,7 @@ class TestObject < Test::Unit::TestCase
attr_accessor :foo
}
obj = klass.new.freeze
- assert_raise_with_message(RuntimeError, /#{name}/) {
+ assert_raise_with_message(FrozenError, /#{name}/) {
obj.foo = 1
}
end
@@ -399,7 +399,7 @@ class TestObject < Test::Unit::TestCase
def test_remove_method
c = Class.new
c.freeze
- assert_raise(RuntimeError) do
+ assert_raise(FrozenError) do
c.instance_eval { remove_method(:foo) }
end
@@ -807,7 +807,7 @@ class TestObject < Test::Unit::TestCase
class<