diff options
-rw-r--r-- | eval.c | 21 | ||||
-rw-r--r-- | spec/ruby/core/refinement/append_features_spec.rb | 21 | ||||
-rw-r--r-- | spec/ruby/core/refinement/extend_object_spec.rb | 21 | ||||
-rw-r--r-- | spec/ruby/core/refinement/prepend_features_spec.rb | 21 | ||||
-rw-r--r-- | test/ruby/test_refinement.rb | 4 |
5 files changed, 83 insertions, 5 deletions
@@ -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"); diff --git a/spec/ruby/core/refinement/append_features_spec.rb b/spec/ruby/core/refinement/append_features_spec.rb new file mode 100644 index 0000000000..fb84f245bd --- /dev/null +++ b/spec/ruby/core/refinement/append_features_spec.rb @@ -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 diff --git a/spec/ruby/core/refinement/extend_object_spec.rb b/spec/ruby/core/refinement/extend_object_spec.rb new file mode 100644 index 0000000000..e44e9f46d8 --- /dev/null +++ b/spec/ruby/core/refinement/extend_object_spec.rb @@ -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 diff --git a/spec/ruby/core/refinement/prepend_features_spec.rb b/spec/ruby/core/refinement/prepend_features_spec.rb new file mode 100644 index 0000000000..9fdea199a2 --- /dev/null +++ b/spec/ruby/core/refinement/prepend_features_spec.rb @@ -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 diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index 0f85fbc922..c0754d8cf0 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -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 |