Remove Refinement#{extend_object,append_features,prepend_features}
Also make include, prepend, and extend raise a TypeError if one of the modules is a refinement. Implements [Feature #18270]
This commit is contained in:
parent
f22296d27e
commit
791343b5bb
Notes:
git
2022-01-06 03:59:29 +09:00
21
eval.c
21
eval.c
@ -1133,8 +1133,12 @@ rb_mod_include(int argc, VALUE *argv, VALUE module)
|
||||
}
|
||||
|
||||
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
||||
for (i = 0; i < argc; i++)
|
||||
for (i = 0; i < argc; i++) {
|
||||
Check_Type(argv[i], T_MODULE);
|
||||
if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
|
||||
rb_raise(rb_eTypeError, "Cannot include refinement");
|
||||
}
|
||||
}
|
||||
while (argc--) {
|
||||
rb_funcall(argv[argc], id_append_features, 1, module);
|
||||
rb_funcall(argv[argc], id_included, 1, module);
|
||||
@ -1186,8 +1190,12 @@ rb_mod_prepend(int argc, VALUE *argv, VALUE module)
|
||||
CONST_ID(id_prepended, "prepended");
|
||||
|
||||
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
||||
for (i = 0; i < argc; i++)
|
||||
for (i = 0; i < argc; i++) {
|
||||
Check_Type(argv[i], T_MODULE);
|
||||
if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
|
||||
rb_raise(rb_eTypeError, "Cannot prepend refinement");
|
||||
}
|
||||
}
|
||||
while (argc--) {
|
||||
rb_funcall(argv[argc], id_prepend_features, 1, module);
|
||||
rb_funcall(argv[argc], id_prepended, 1, module);
|
||||
@ -1741,8 +1749,12 @@ rb_obj_extend(int argc, VALUE *argv, VALUE obj)
|
||||
CONST_ID(id_extended, "extended");
|
||||
|
||||
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
|
||||
for (i = 0; i < argc; i++)
|
||||
for (i = 0; i < argc; i++) {
|
||||
Check_Type(argv[i], T_MODULE);
|
||||
if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {
|
||||
rb_raise(rb_eTypeError, "Cannot extend object with refinement");
|
||||
}
|
||||
}
|
||||
while (argc--) {
|
||||
rb_funcall(argv[argc], id_extend_object, 1, obj);
|
||||
rb_funcall(argv[argc], id_extended, 1, obj);
|
||||
@ -2041,6 +2053,9 @@ Init_eval(void)
|
||||
rb_undef_method(rb_cClass, "refine");
|
||||
rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
|
||||
rb_define_method(rb_cRefinement, "refined_class", rb_refinement_module_get_refined_class, 0);
|
||||
rb_undef_method(rb_cRefinement, "append_features");
|
||||
rb_undef_method(rb_cRefinement, "prepend_features");
|
||||
rb_undef_method(rb_cRefinement, "extend_object");
|
||||
|
||||
rb_undef_method(rb_cClass, "module_function");
|
||||
|
||||
|
21
spec/ruby/core/refinement/append_features_spec.rb
Normal file
21
spec/ruby/core/refinement/append_features_spec.rb
Normal file
@ -0,0 +1,21 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
describe "Refinement#append_features" do
|
||||
ruby_version_is "3.2" do
|
||||
it "is not defined" do
|
||||
Refinement.should_not have_private_instance_method(:append_features)
|
||||
end
|
||||
|
||||
it "is not called by Module#include" do
|
||||
c = Class.new
|
||||
Module.new do
|
||||
refine c do
|
||||
called = false
|
||||
define_method(:append_features){called = true}
|
||||
proc{c.include(self)}.should raise_error(TypeError)
|
||||
called.should == false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
spec/ruby/core/refinement/extend_object_spec.rb
Normal file
21
spec/ruby/core/refinement/extend_object_spec.rb
Normal file
@ -0,0 +1,21 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
describe "Refinement#extend_object" do
|
||||
ruby_version_is "3.2" do
|
||||
it "is not defined" do
|
||||
Refinement.should_not have_private_instance_method(:extend_object)
|
||||
end
|
||||
|
||||
it "is not called by Object#extend" do
|
||||
c = Class.new
|
||||
Module.new do
|
||||
refine c do
|
||||
called = false
|
||||
define_method(:extend_object){called = true}
|
||||
proc{c.extend(self)}.should raise_error(TypeError)
|
||||
called.should == false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
spec/ruby/core/refinement/prepend_features_spec.rb
Normal file
21
spec/ruby/core/refinement/prepend_features_spec.rb
Normal file
@ -0,0 +1,21 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
describe "Refinement#prepend_features" do
|
||||
ruby_version_is "3.2" do
|
||||
it "is not defined" do
|
||||
Refinement.should_not have_private_instance_method(:prepend_features)
|
||||
end
|
||||
|
||||
it "is not called by Module#prepend" do
|
||||
c = Class.new
|
||||
Module.new do
|
||||
refine c do
|
||||
called = false
|
||||
define_method(:prepend_features){called = true}
|
||||
proc{c.prepend(self)}.should raise_error(TypeError)
|
||||
called.should == false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -1919,10 +1919,10 @@ class TestRefinement < Test::Unit::TestCase
|
||||
m = Module.new do
|
||||
r = refine(String) {def test;:ok end}
|
||||
end
|
||||
assert_raise_with_message(ArgumentError, /refinement/, bug) do
|
||||
assert_raise_with_message(TypeError, /refinement/, bug) do
|
||||
m.module_eval {include r}
|
||||
end
|
||||
assert_raise_with_message(ArgumentError, /refinement/, bug) do
|
||||
assert_raise_with_message(TypeError, /refinement/, bug) do
|
||||
m.module_eval {prepend r}
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user