mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 04:07:58 +00:00
Use rb_error_frozen_object in rb_class_modify_check
This provides information on the class of the frozen object. It also results in a much simpler implementation. Fixes [Bug #21374]
This commit is contained in:
parent
76fb0d244b
commit
e436dba9fe
Notes:
git
2025-12-09 22:36:21 +00:00
32
eval.c
32
eval.c
@ -428,40 +428,10 @@ rb_class_modify_check(VALUE klass)
|
||||
rb_class_set_initialized(klass);
|
||||
}
|
||||
if (OBJ_FROZEN(klass)) {
|
||||
const char *desc;
|
||||
|
||||
if (RCLASS_SINGLETON_P(klass)) {
|
||||
desc = "object";
|
||||
klass = RCLASS_ATTACHED_OBJECT(klass);
|
||||
if (!SPECIAL_CONST_P(klass)) {
|
||||
switch (BUILTIN_TYPE(klass)) {
|
||||
case T_MODULE:
|
||||
case T_ICLASS:
|
||||
desc = "Module";
|
||||
break;
|
||||
case T_CLASS:
|
||||
desc = "Class";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (BUILTIN_TYPE(klass)) {
|
||||
case T_MODULE:
|
||||
case T_ICLASS:
|
||||
desc = "module";
|
||||
break;
|
||||
case T_CLASS:
|
||||
desc = "class";
|
||||
break;
|
||||
default:
|
||||
Check_Type(klass, T_CLASS);
|
||||
UNREACHABLE;
|
||||
}
|
||||
}
|
||||
rb_frozen_error_raise(klass, "can't modify frozen %s: %"PRIsVALUE, desc, klass);
|
||||
rb_error_frozen_object(klass);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -26,9 +26,11 @@ describe "FrozenError#message" do
|
||||
object = Object.new
|
||||
object.freeze
|
||||
|
||||
msg_class = RUBY_VERSION >= "4" ? "Object" : "object"
|
||||
|
||||
-> {
|
||||
def object.x; end
|
||||
}.should raise_error(FrozenError, "can't modify frozen object: #{object}")
|
||||
}.should raise_error(FrozenError, "can't modify frozen #{msg_class}: #{object}")
|
||||
|
||||
object = [].freeze
|
||||
-> { object << nil }.should raise_error(FrozenError, "can't modify frozen Array: []")
|
||||
|
||||
@ -97,7 +97,8 @@ describe "An instance method" do
|
||||
def foo; end
|
||||
end
|
||||
}.should raise_error(FrozenError) { |e|
|
||||
e.message.should == "can't modify frozen module: #{e.receiver}"
|
||||
msg_class = RUBY_VERSION >= "4" ? "Module" : "module"
|
||||
e.message.should == "can't modify frozen #{msg_class}: #{e.receiver}"
|
||||
}
|
||||
|
||||
-> {
|
||||
@ -106,7 +107,8 @@ describe "An instance method" do
|
||||
def foo; end
|
||||
end
|
||||
}.should raise_error(FrozenError){ |e|
|
||||
e.message.should == "can't modify frozen class: #{e.receiver}"
|
||||
msg_class = RUBY_VERSION >= "4" ? "Class" : "class"
|
||||
e.message.should == "can't modify frozen #{msg_class}: #{e.receiver}"
|
||||
}
|
||||
end
|
||||
end
|
||||
@ -283,7 +285,8 @@ describe "A singleton method definition" do
|
||||
it "raises FrozenError with the correct class name" do
|
||||
obj = Object.new
|
||||
obj.freeze
|
||||
-> { def obj.foo; end }.should raise_error(FrozenError, "can't modify frozen object: #{obj}")
|
||||
msg_class = RUBY_VERSION >= "4" ? "Object" : "object"
|
||||
-> { def obj.foo; end }.should raise_error(FrozenError, "can't modify frozen #{msg_class}: #{obj}")
|
||||
|
||||
obj = Object.new
|
||||
c = obj.singleton_class
|
||||
|
||||
@ -601,7 +601,7 @@ class TestClass < Test::Unit::TestCase
|
||||
obj = Object.new
|
||||
c = obj.singleton_class
|
||||
obj.freeze
|
||||
assert_raise_with_message(FrozenError, /frozen object/) {
|
||||
assert_raise_with_message(FrozenError, /frozen Object/) {
|
||||
c.class_eval {def f; end}
|
||||
}
|
||||
end
|
||||
|
||||
@ -3016,17 +3016,17 @@ class TestModule < Test::Unit::TestCase
|
||||
bug11532 = '[ruby-core:70828] [Bug #11532]'
|
||||
|
||||
c = Class.new {const_set(:A, 1)}.freeze
|
||||
assert_raise_with_message(FrozenError, /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(FrozenError, /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(FrozenError, /frozen class/, bug11532) {
|
||||
assert_raise_with_message(FrozenError, /frozen Class/, bug11532) {
|
||||
c.class_eval {deprecate_constant :A}
|
||||
}
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user