aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--eval.c21
-rw-r--r--spec/ruby/core/refinement/append_features_spec.rb21
-rw-r--r--spec/ruby/core/refinement/extend_object_spec.rb21
-rw-r--r--spec/ruby/core/refinement/prepend_features_spec.rb21
-rw-r--r--test/ruby/test_refinement.rb4
5 files changed, 83 insertions, 5 deletions
diff --git a/eval.c b/eval.c
index 34c5d6ff85..d91440676f 100644
--- a/eval.c
+++ b/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");
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